Chapter 21: Figures, Sounds and Files
21.12. Writing and reading tables to external files

The main use for files is to store and retrieve data, and the most flexible form of data used by Inform is the Table, so facilities are provided which make it as easy as possible to write and read the contents of a table to files.

To save the contents of a table to a file, we use the phrase:

write File of Glaciation Data from the Table of Antarctic Reserves

naming the file (which should be one already declared) and specifying which table it should come from. To load a file back into a table,

read File of Glaciation Data into the Table of Antarctic Reserves

We can check if a file already exists using:

if File of Glaciation Data exists, ...

On writing a table, any blank rows are automatically moved to the bottom, and only the non-blank rows are written; on reading a file back in, any rows left spare at the foot of the table are automatically blanked. On the other hand if the file is too large to fit into the table - with too many columns or too many rows - a run-time problem is produced.

One unfortunate restriction must be kept in mind. Some of what is stored in tables is solid information whose meaning never changes: the number 342, for instance, means the same to everyone. But other information depends entirely on the current location of certain structures in memory - for instance, a rule is internally referred to by its memory location. This potentially changes each time Go or Replay is clicked, and so it is not safe to pass it from one copy to another, or from one project to another. The only tables which Inform allows us to write into files are those containing "safe" data: numbers, units, times of day and kinds of value with named alternatives. Scenes, rules or rulebooks, in particular, are not allowed.

And nor is text - but we can easily get around that, because indexed text (see the previous chapter) is. For instance, the following table can legally be written out to a file, weareas it would have thrown up a run-time problem if we tried it with the surface column defined simply as text:

Table of Neptune's Moons
moon   surface (indexed text)   
1   "utterly unknown"   
2   "cryovolcanic ridges"   
3   "highly irregular and sooty"   


381
* Example  Alien Invasion Part 23
Keeping a preference file that could be loaded by any game in a series.

RB

Suppose that we have a series of games each of which allows the player to select a puzzle difficulty level. When the player plays a new game in the series, we want him to start out by default with the same difficulty level he faced earlier on, so we store this information in a small preferences file, as follows:

"Alien Invasion Part 23"

A difficulty is a kind of value. The difficulties are easy, moderate, hard, and fiendish.

Understand "use [difficulty] puzzles" as selecting difficulty. Selecting difficulty is an action out of world, applying to one difficulty.

Carry out selecting difficulty:
    choose row 1 in the Table of Preference Settings;
    change challenge level entry to difficulty understood;
    say "Puzzles will be [challenge level entry] from now on."

The File of Preferences is called "prefs".

When play begins:
    if File of Preferences exists
    begin;
        read File of Preferences into the Table of Preference Settings;
        choose row 1 in the Table of Preference Settings;
        say "(The current puzzle difficulty is set to [challenge level entry].)";
    end if.

Check quitting the game:
    write File of Preferences from the Table of Preference Settings;

Table of Preference Settings
challenge level
easy

The Sewer Junction is a room.

Our preference file is restricted to a single option here for simplicity's sake, but we could keep track of more information -- whether the player preferred verbose or brief room descriptions, screen configurations, and so on.

If we were disposed to be somewhat crueler, we could use a similar method to make the player finish each episode of the series in order to "unlock" the next. All we would need to do is store a numerical password in our preferences file when the player finished a given level; the next level would check, say, the Table of Completed Levels for that password, and refuse to play unless the right number were present.

382
** Example  Labyrinth of Ghosts
Remembering the fates of all previous explorers of the labyrinth.

RB
383
*** Example  Rubies
A scoreboard that keeps track of the ten highest-scoring players from one playthrough to the next, adding the player's name if he has done well enough.

RB


PreviousContentsNext