# Writing a Game in the Past Tense

by Michel Nizette

## Adapted for Adv3Lite by Eric Eve

The adaptation is fairly slight here, since adv3Lite handles this quite similarly to the way adv3 does.

## Introduction

IF authors usually prefer to write in the second person and in the present tense, as though the events were happening directly to the player. Many feel that this creates a sense of involvement in the story that cannot be so efficiently achieved otherwise. Occasionally, though, some authors like to break free of this tradition and explore how a different narrative style affects the playing experience. For example, a first-person game presented in the form of a dialogue between the player and the protagonist of the story may help establish the latter as a distinct character, with an independent personality. The past tense also can be used to good effect to evoke the protagonist's memories, either for the whole story or during a short interlude.

Before TADS 3, experimenting with these unusual narrative styles wasn't easy, and required a lot of work on the part of the author. All IF authoring systems provide a set of default responses to the player's actions, and many games don't need to replace more than a few of them. However, these messages are usually written in the second person and in the present tense, according to the most widespread usage. This means that the whole set of messages have to be replaced if you want to try a different combination of person and tense.

In TADS 3, the person and tense aren't hard-coded in the message definitions. Instead, TADS 3 uses parameterized messages that automatically adapt to the combination of person and tense of your choice, which you specify simply via a couple of settings. As a result of this design, you are not restricted to use the same tense and person for the whole story: you can switch to a different combination at any time during the game.

## Selecting the person and tense of the narrative

You select the narrative tense via the usePastTense property of your gameMain object. This is the object where you define the initial player character and the messages displayed during the introduction and after quitting. The default value of usePastTense is nil, meaning that, by default, the story uses the present tense. Override this property to true for a past tense narrative.

You can reset this property at any time during the game to switch to a different tense. The adv3Lie Library defines a convenience macro for this, called setPastTense. This macro takes a single argument and is just a shorthand for assigning gameMain.usePastTense directly: setPastTense(val) simply expands to gameMain.usePastTense = val.

Unlike the narrative tense, the person in which the player character is referred to is a property of the player character's Actor object. In a game where several characters can be controlled by the player at different times, you might want to use distinct grammatical persons for some of them, so it makes sense to define this setting separately for each potential player character. To select the person for the player character object, you set its person property to one of the three following values: 1, 2, or 3. The default value is 2, so that the game refers to the player character as "you" unless otherwise specified.

In adv3Lite you can also set the tense on the Narrator object (Narrator.tense) to one of six tenses:

- Present, e.g., Bob opens the box.
- Past: Bob opened the box.
- Perfect: Bob has opened the box.
- Past Perfect: Bob had opened the box.
- Future: Bob will open the box.
- Future Perfect: Bob will have opened the box.

Narrator.Present defaults to Present, but we don't have to worry about the Narrator object at all if we're only interested in using the present and/or part tense. Since tenses other than these two are so rare in Interactive Fiction, for the rest of this article we shall focus almost entirely on the past and present tenses.

## The past tense handling framework

The ability to switch between the present tense and the past tense relies on the message parameter substitution mechanism used for plugging the appropriate object names in the command responses and making verbs agree in person and number with the subject. The remainder of this article describes the features of the substitution parameter framework that are specific to handling the past tense. From now on, we'll assume that you have some familiarity with message substitution parameters.

If you have read the article in question, you have probably noticed that the first given example of a message that uses substitution parameters:

        {I} {see} nothing unusual about {it dobj}.

Although the verb "see" could be considered regular as long as we were only interested in the present-tense form, and could be handled with the regular verb ending parameter {s}, it can't be anymore now that we need to take the irregular past tense form ("saw") into account. The parameter {sees} generates the appropriate conjugated form of "see" in agreement with the subject of the sentence and in the desired tense: it produces "sees" in the third-person singular of the present tense, "see" in all other cases of the present tense, and "saw" in the past tense. The irregular verb "see," just like "have," is common enough to justify a dedicated substitution parameter. Many other irregular verbs have their own specific substitution parameters. We'll see below how to conjugate arbitrary verbs, whether regular or irregular.

## Regular verb endings

Regular verbs are those that obey simple conjugation rules in both the present tense and the past tense: up to some minor variations, they take -s in the third-person singular of the present tense and -ed in the past tense. The parameters relevant to conjugating verbs in either the present or the past tense are:

Parameter string | Example use | Example expansion
--- | --- | ---
s/d | close{s/d} | close, closes, closed
s/ed | open{s/ed} | open, opens, opened
s/?ed | drop{s/?ed} | drop, drops, dropped
es/ed | fix{es/ed} | fix, fixes, fixed
ies/ied | carr{ies/ied} | carry, carries, carried

Their use should be mostly self-explanatory from the examples given in the two last columns of the table, but a few comments are worth making.

The two first parameters, {s/d} and {s/ed}, are used for those verbs that just take -s in the third-person singular present: some of them take -d in the past (like "close") and thus require {s/d}, and others take -ed (like "open") and thus require {s/ed}. The parameter {s} doesn't contain enough information to lift this ambiguity, and should be used only in those contexts where you are certain that you don't need the past-tense form (more about this later).

The parameter {s/?ed} is handled in a special way by the Library. It is used for those verbs that end with a consonant and have that last consonant repeated in the past tense, but otherwise have a regular conjugation. The example listed in the table is "drop," which has its final 'p' repeated in the past: "dropped." To use this parameter, you type it literally with the explicit question mark. The library then replaces the question mark with the repeated consonant.

The two last parameters in the table, {es/ed} and {ies/ied}, are respectively for those verbs that take -es or have their -y ending replaced with -ies in the third-person singular present. Note that, unlike {s}, the verb endings {es} and {ies} actually contain no ambiguity about the corresponding regular past tense form, since -es always becomes -ed, and -ies always becomes -ied in the past. So, the parameters {es/ed} and {ies/ied} are actually redundant, and are in fact equivalent to {es} and {ies}, respectively. They only are provided for symmetry with the {s/d}, {s/ed}, {s/?ed} set. We recommand that you always use the parameter forms that explicitly list the past tense ending in all cases, so that you never need to think about which case truly requires it and which does not.

## Common irregular verbs

The adv3Lite library defines substitution parameters for about two hundred verbs that have an irregular form in the past tense. Some common ones include:

Parameter strings | Expands to
--- | ---
do, does | do, does, did
go, goes | go, goes, went
come, comes | come, comes, came
leave, leaves | leave, leaves, left
see, sees | see, sees, saw
say, says | say, says, said
must | must, had to
can | can, could
cannot | cannot, could not
can't | can't, couldn't
will | will, would
won't | won't, wouldn't

You can see from the table that if a verb or verb form is defective in the past tense, then the corresponding parameter expands to a close approximation: {must} expands to "had to," and {cannot} expands to "could not." Also, for some verbs, there are two equivalent parameter strings: for example, {do} and {does} have exactly the same expansion rules.

## Arbitrary irregular verbs

For rarely used irregular verbs, the Library providest two fallback mechanisms. One allows switching between two arbitrary strings depending on the narrative tense. The format superficially looks like an ordinary substitution parameter: the syntax is {presentString|pastString}, where presentString and pastString represent the (possibly empty) strings to be displayed in the present and past tenses, respectively.

For example, the substring {may|might} in a parameterized message string would expand to "may" in the present tense and to "might" in the past tense. (We don't actually needs to do this since the library understands {may} perfectly well).

This example is rather exceptional in that the verb "may" doesn't vary at all in the present tense. Most irregular verbs need to be made to agree with the subject in the present tense. Let's imagine we had the rare verb 'to frob' which become 'he frobs' in the third person preseny, 'he frub' in the past, and 'he has frabbed' in the past perfect. We can tell the library how to cope with a new {frob} parameter by adding it to a CustomVocab object:

    CustomVocab
        verbParams = ['frob/frobs/frub/frabbed']
    ;

Then we could write messages like:

       "<.p>{I} hardly {frob} Blottnyan poetry. ";

And it would expand into "You hardly frob Blottnyan poetry", "Fred hardly frobs Blottyan poetry", "You hardly frub Blottnyan poetry" (back then) or "You have hardly frabbed Blottnyan poetry" as appropriate.

The verbParams property of a CustomVocab object holds a list of strings, using the following template:

     'infinitive/present3/past/past-participle'

The 'infinitive' is the 'to' form of the verb (to go, to look, to see), but without the word 'to'. 'present3' is the third-person present form (is, goes, sees). 'past' is the past tense form went, looked, saw). 'past-participle' is the past participle form; this is optional, and is needed only for verbs with distinct past and past participle forms (e.g., saw/seen, went/gone). Most regular verbs - those with the past formed by adding -ed to the infinitive - have identical past and participle forms.

For every English verb except "to be", the entire present and past conjugations can be derived from these three bits of information. The past perfect, future, and future perfect conjugations can also be derived from this information, for any verb except "to be" and the auxiliary verbs (could, should, etc). The English library pre-defines "to be" and all of the auxiliary verbs, so there's no need to define those with this mechanism.

## Arbitrary tense-dependent expressions

The tense-switching syntax can also be useful for more complicated verb forms, or for things other than verbs but that still vary with tense. For example, we could define:

       {The subj dobj} should {be|have been} right {|t}here,
       but {I} {can\'t} see {him dobj}.

In this example, the tense-switching syntax is used twice. The first instance generates a present or past conditional: the substring "should {be|have been}" produces "should be" in the present tense, and "should have been" in the past tense. The second instance is "{|t}here," which gives "here" in the present tense and "there" in the past tense. (In case you wonder, the reason why we want to avoid using "here" in the past tense is that it doesn't make much sense to call "here" a place which the player character has visited at some time in the past, but might very well have left since then.)

Note also an important difference between the two following messages:

       {I} smell{s/ed} nothing out of the ordinary.

       Opening {the dobj} reveal{s|ed} nothing unusual.

You may wonder why the first message uses the ordinary verb ending substitution parameter {s/ed}, whereas the second message uses the generic tense-switching syntax {s|ed}, for apparently identical purposes. The answer is that ordinary verb parameters need a subject to agree with, while the tense-switching syntax doesn't. In the first message, the parameter {I} sets up the grammatical subject of the sentence. The verb "smell" is then required to agree with it, so we must use the appropriate substitution parameter for the verb ending. In the second message, the subject of the sentence is the present participle "Opening," which unconditionally requires the verb to be in third-person singular. Because the subject isn't a parameterized expression, we don't need (and we can't use) a verb ending parameter here. But the verb ending still needs to vary with tense, so we use the tense-switching syntax.

An alternative here would have been to use the parameter string {dummy} to stand in for the subject of the verb without outputting any text:

        Opening {the dobj} {dummy} reveal{s/ed} nothing unusual.

Behind the scenes, the tense-switching syntax is implemented via a macro which you may find convenient in its own right. The macro is named tSel and takes two arguments; it just expands to its first argument if the current narrative tense is the present, and to its second argument if it is the past. For example, tSel(getTime()[1], 1492) would give the current year for the present tense, and the year of the discovery of America by Columbus for the past tense.

## Disabling tense switching in substitution parameters

Occasionally, you may want a verb form to vary as a function of person and number only, but not as a function of the narrative tense. Quoted speech, for example, is always reported in the present tense, even in a past tense narrative.

You might be tempted to write a default response to giving an arbitrary object to a certain character as follows:

       {The subj iobj} {says}, <q>{The subj dobj} {is} of no use to me right now.</q>

except that this won't quite work as you want it to, at least in the past tense. The kind of response you are aiming for with such a message string is probably something like "The thief said, 'the lock pick is of no use to me right now.'" But instead, it will generate "The thief said, 'the lock pick was of no use to me right now,'" because the system has no way to know that you want the verb "is" in the present tense, despite this being a past-tense phrasing. Yet you really need a substitution parameter for the verb "is," because it must agree in number with the direct object of the action. This is obvious from the following example: "The thief said, 'the gloves are of no use to me right now.'"

TADS 3 (and adv3Lite) provide a solution to this problem. Just add an exclamation mark at the end of the substitution parameter for which you want the present-tense form unconditionally, like this:

       {The subj iobj} {says}, <q>{The subj dobj} {is!} of no use to me right now.</q>

The Library then will not attempt to render the verb "to be" in the past tense, but still knows that you want it to agree with the subject.

There is another situation where this mechanism can be useful. If your whole game is written in the past tense, then the only verb for which you'll ever need a substitution parameter is the verb "to be," whose conjugated forms are "was" and "were." All other verbs have the same form for any person and number in the past tense, so they have no agreement rules to worry about: you can just type them out literally, without using substitution parameters. For the verb "to be," the straightforward way to proceed would be to use {are} or {is}. But since most of the text is going to be written in the past tense, you may not like the intrusion of parameters that look formally like present-tense verb forms. And you can't use {was} or {were} for this purpose, because both of them would expand to "had been" (which is really equivalent to "was" or "were" with a second layer of past added!) Note, however, that in the situation we're considering, you don't care about having your text correctly rendered in the present tense, so you may just as well use {was!} or {were!}, with final exclamation marks. These always give the past-tense form of the verb "to be" that agrees with the subject.

Adv3Lite also provides a function named withTense, whose purpose is to temporarily override the current narrative tense and to invoke and return the value of a callback function within the new, temporary tense context. The function withTense takes two arguments. The first one must be either nil (selecting the present tense) or true (selecting the past tense). The second argument is a reference to the callback function.

The Adv3Lite Library complements this function with two convenience macros, named withPresent and withPast. They simply call the function withTense with a nil or true first argument, respectively. Both macros take a single argument, which is the callback function to be passed to withTense.

TADS 3 Technical Manual
Table of Contents | Advanced Topics > Writing a Game in the Past Tense
Prev: Using Nested Rooms as Staging Locations Next: Internet Media Types for TADS