Bibliographic Metadata in TADS Games: GameInfo version 1.2
TADS has a mechanism that lets you include bibliographic information - title, author, release date, etc. - directly in your compiled game file. The information is essentially a "card catalog" entry for your game. This system is called the "GameInfo" format, and it's what's known as a "metadata" system.
What's the point of this, you might wonder? After all, most games already display their title and author and so on when they start up; so why go to the additional trouble of filling in this card catalog entry? Well, consider the plight of someone who has a few dozen TADS .gam files sitting on their hard disk, and they want to find a particular one, but they don't remember its filename. If they had to rely on the game's own title screen, they'd have to run each game in turn, maybe clicking through a few initial screens and hunting through a few paragraphs of text, before they found the right one. Now consider the problem for the maintainers of the IF Archive, who have several hundred TADS games to keep track of - along with hundreds of games from other systems. It's a huge job to track all of that information manually; it would be a big help if even some of it could be automated.
The point of the GameInfo data, then, is that it lets you get at the bibliographic data for a game without having to run the game and read the title screen. What's more, it puts the information in a standard, structured format that lets automated tools unambiguously identify particular parts of the information. For example, a tool that wants to present you a list of games sorted by the author's name could find that information using the GameInfo data.
As time goes on, we expect that archiving tools and interpreters will increasingly use IF metadata to improve the user experience of working with IF games. Already, the HTML TADS interpreter on Windows uses GameInfo records to enhance its Game Chest feature. The Game Chest presents the user with more information than just a filename - Game Chest can show the full title of a game, the author, and a short blurb, before the player even decides to fire up the game.
This article explains how the GameInfo system works and how to use it. Most authors will just want to look at the following sections, which have the practical how-to information you need to start using GameInfo in your own games:
The following sections describe the inner workings of the GameInfo format itself. These are a bit more technical, but most authors can safely skip these sections, since the TADS tools take care of the technical details for you automatically. These sections are intended more for people who want to write new tools that extract or work with GameInfo data.
- GameInfo and the iFiction standard (the "Treaty of Babel")
- Creating custom name/value definitions
- Unicode and UTF-8 encoding
- Storage format specification
- Sample gameinfo.txt file
- Extraction utilities
- Revision history
A GameInfo record is simply a list of name/value pairs defining specific bits of information about the game. Each name/value pair consists of a standard identifier - the "name" - and an associated value. Each name has a specific meaning, and defines a specific format for its value. For example, to specify a game's title, you specify value for the "Name" identifier; the value is simply a string giving the full title of the game.
Name/Value pairs every game should have
All of the name/value pairs are optional. However, to improve interoperability with the IF Archive and various tools, we recommend that you minimally define the following in every game:
- IFID
- Name
- AuthorEmail
The iFiction standard requires the information that these tags define, so to interoperate properly with the IF Archive and other iFiction-based systems, you should always define these tags.
The Name/Value pairs in detail
The standard, pre-defined Name/Value pairs are as follows:
IFID
Format: xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Example: IFID: 17AF6C-990E-7220-06F7-3962AA61F09A
TADS 3 versionInfo example: IFID = '17AF6C-990E-7220-06F7-3962AA61F09A'
The IFID is the game's universally unique identifier. Refer to
the IFID section for full details on this
field. Note that you can specify multiple IFIDs here by separating
them with commas - but do this only to encode legacy
IFIDs for past releases that didn't include IFIDs, as described
in the IFID section.
Name
Format: Any text
Example: Name: Mars by Night
TADS 3 versionInfo example: name = 'Mars by Night'
The full title of the game, as it should appear in plain text.
Headline
Format: Any text
Example: Headline: An Interactive Rescue
TADS 3 versionInfo example: headline = 'An Interactive Rescue'
A subtitle for the game, following the tradition set by the
Infocom games. This is usually something like "An Interactive Mystery"
that you display just after the title of your game at startup.
Byline
Format: Any text
Example: Byline: by S.F. Author
TADS 3 versionInfo example: byline = 'by S.F. Author'
Name of the author or authors of the game, as it should appear in
a plain text credit. The byline is meant to be displayed after the
name of the game, so it can include phrasing like "by author"
if desired.
HtmlByline
Format: HTML source text
Example: HtmlByline: by S.F. Author
TADS 3 versionInfo example: htmlByline = 'by S.F. Author'
Name of the author or authors of the game, as it should appear in
HTML. This should contain roughly the same information as the
"Byline" field, but can include HTML markups in its value. It is
desirable (although not required) for this field to incorporate
<A HREF='mailto:'> tags to provide email address hyperlinks
for the authors.
Note that if the HtmlByline field is present, a regular Byline
field should be included as well, so that the plain text version of
the information is available to tools that can't handle HTML.
AuthorEmail
Format: Name <email>
<email>; ...
Example: AuthorEmail: S.F. Author <sfauthor@mywebsite.org>
TADS 3 versionInfo example: authorEmail = 'S.F. Author <sfauthor@mywebsite.org>'
Names and email addresses of the authors. Each author can have
one or more email addresses listed in angle brackets after the
author's human-readable name. Multiple authors can be listed by
separating the entries with semicolons. You should only include email
addresses that are likely to be valid for the foreseeable future,
since games uploaded to the IF Archive will be stored indefinitely.
Url
Format: http://...
Example: Url: http://mywebsite.org/marsbynight.htm
TADS 3 versionInfo example: gameUrl = 'http://mywebsite.org/marsbynight.htm'
The URL for the game's web site. This must be an absolute
URL with http: as the protocol. Since IF games that are uploaded
to the Archive will be stored indefinitely, people might be looking
at this information well into the future; so we recommend that
you only include a URL if your site is likely to be around for a while.
Desc
Format: Any text
Example: Desc: All contact lost with the first manned mission...
TADS 3 versionInfo example: desc = 'All contact lost with the first manned mission...'
A plain text description of the game. This is a "blurb" describing
the game - the sort of thing you'd find on the inside jacket of a
book, or on the back of the box for a computer game. This is "plain"
text in the sense that it can't contain any formatting - HTML markups
aren't allowed, for example. There's one exception: if you want to
include a paragraph break, you can write \n - that is, a
backslash followed by a lower-case 'n'. When displayed, this will
usually appear as two line breaks in a row, so that there's
a blank line between paragraphs. If you want to write just
a backslash, use two in a row (\\) - this is so that there
will be no confusion if the backslash happens to be followed by an
'n', and also so that we can safely add new backslash sequences in
the future if they're ever needed.
HtmlDesc
Format: HTML source text
Example: HtmlDesc: <i>All contact lost</i> with the first...
TADS 3 versionInfo example: htmlDesc = '<i>All contact lost</i> with the first...'
HTML description of the game. This should contain roughly the same
information as the "Desc" field, but this field can contain HTML markups
in its value. Note that if an HtmlDesc is given, a regular Desc should
be given as well, because some tools that use the game information are
not capable of handling HTML.
The HtmlDesc is typically an approximate superset of the Desc text - in most cases, it'll be the Desc text plus some HTML formatting codes. So you might wonder why you need to provide both versions: why doesn't the computer just strip the HTML tags out of the HtmlDesc, and use that as the plain-text version? The answer is that the correspondence isn't always exact. In some cases, you'll want to tweak the plain text a little to compensate for the loss of the HTML formatting; you might want to use ALL CAPS for some words for emphasis, for example. The computer can't be relied upon to do this kind of subtle adjustment on its own; it's better to be able to specify exactly what you want. That's why we define the two fields as separate values.
Version
Format: Any text
Example: Version: 2
TADS 3 versionInfo example: version = '2'
The version number string for the game. This is usually just a
number, like "2" for version 2. There's a tradition in computer
software of using elaborate "dotted" version numbers with a multitude
of sub-parts, as in "2.5.7.11.14B"; but most IF games see only a
handful of releases, so a simple one-part version number ("2") is
usually quite adequate. You shouldn't include the word "version" in
this string - just include the version number information.
FirstPublished
Format: YYYY or YYYY-MM-DD
Example: FirstPublished: 2003
TADS 3 versionInfo example: firstPublished = '2003'
The date of first publication for the game's original
edition. This can be either a year, or a full year-month-day (March
5, 2001 would be written "2001-03-05"). The date of first publication
of a work is sometimes important for copyright purposes, and can be of
interest to archivists. Note that this does not change with
version updates - this reflects the original publication date of the
original version of the game.
ReleaseDate
Format: YYYY-MM-DD
Example: ReleaseDate: 2006-04-10
TADS 3 versionInfo example: releaseDate = '2006-04-10'
The release date of this version of the game. (Note that the format
specifies the year, month, and day of release in numeric format: March 5,
2001 is rendered as "2001-03-05".)
Language
Format: RFC3066
language specifier
Example: Language: en-US
TADS 3 versionInfo example: languageCode = 'en-US'
The language in which the work's text is written (or primarily
written, if the work uses multiple languages). This information can
help potential users identify works written in languages they know,
and could also be used as a hint to text-to-speech converters or
other natural language analysis tools. For simplicity, it is
recommended that the language identifier string consist of
an ISO-639
two- or three-letter language code, followed by a hyphen and
an ISO-3166
two-letter country code, but any valid RFC3066 specifier is allowed.
For English, typical specifiers would be en-US (for US English)
or en-GB (for British English).
Series
Format: Any text
Example: Series: The Lost Mars Trilogy
TADS 3 versionInfo example: seriesName = 'The Lost Mars Trilogy'
If this work is part of a series, this gives the name of the
series. For example, "The Enchanter Trilogy". If you specify this
tag, you might also want to specify SeriesNumber to indicate the
position of this work in the series, but that's optional - some series
are just groups of related works with no canonical ordering.
SeriesNumber
Format: Integer
Example: SeriesNumber: 1
TADS 3 versionInfo example: seriesNumber = '1'
The sequence number of this work in its series. This should be a
simple integer value - 1 or 2 or 3, not "Part One" or "The Second Book".
This is optional, even if the Series is specified, since a series might
just be a group of works with no defined ordering. If this tag is
specified, the Series must be defined as well.
Genre
Format: Any text
Example: Genre: Science Fiction
TADS 3 versionInfo example: genreName = 'Science Fiction'
The genre that, in the author's opinion, best describes the work.
We recognize that not everyone thinks genre labeling is a good idea -
a lot of authors dislike the whole idea; many works are impossible to
pigeonhole; and if you ask three people the genre of a particular
game, you might well get three different answers. Even so,
realistically, it seems just about inevitable that players and
archivists will try to force even the most singular works into genre
straitjackets. So, we define this tag to give the author the option
of stating her own opinion on the subject.
If you dislike genre tagging, you can just omit this tag. Otherwise, you can use any text you want here, but we suggest that you keep it short (a word or two) and use a genre label that's generally recognized as such. We particularly recommend choosing an entry from Baf's Guide's genre list.
Forgiveness
Format: Text
Example: Forgiveness: Polite
TADS 3 versionInfo example: forgivenessLevel = 'Polite'
This gives the author's estimation of the game's forgiveness level
on the Zarfian scale (as propounded by Andrew Plotkin on
rec.arts.int-fiction. This must have one of these values,
in the exact case shown:
- Merciful - the player cannot get stuck, the PC cannot die
- Polite - you can get stuck or the PC can die, but it's immediately obvious when you're stuck or dead
- Tough - you can get stuck, but it's immediately obvious that you're about to do something irrevocable
- Nasty - you can get stuck, but after you do something irrevocable, it's clear
- Cruel - you can get stuck by doing something that isn't obviously irrevocable, even after doing it
LicenseType
Format: Text
Example: LicenseType: Freeware
TADS 3 versionInfo example: licenseType = 'Freeware'
The type of copyright license under which the game is
distributed. This field is not meant to capture all possible license
information, but is meant to indicate in broad terms how the work is
distributed.
The value should be chosen from the following keywords:
- Public Domain for a work that is not copyrighted;
- Freeware for a work that is made available without charge, but whose author nonetheless retains copyright;
- Shareware for a work distributed on a free-trial basis but with some degree of suggestion or requirement that users pay the author if they choose to use the software;
- Commercial for a work that is distributed only to paying customers
- Commercial Demo for a limited-functionality version, which may be freely distributed, of a full work distributed commercially;
- Other for a work that does not fit any of these categories.
Cases that are substantially similar to one of the categories enumerated above should use the nearest category; for example, "postcard-ware," where users are requested to send postcards to the author if they like the game, could be considered Shareware, because the game is distributed freely but with a request for sending something (token though it is) to the author. Note that this field does not grant or imply any license rights, and is not meant to provide a "digital rights management" system or the like; authors should always include full license terms in a separate text file accompanying the game or in-line as part of the game's displayed text.
CopyingRules
Format: Text
Example: CopyingRules: Nominal Cost Only; Compilations Allowed
TADS 3 versionInfo example: copyingRules = 'Nominal Cost Only; Compilations Allowed'
Information on the rules under which the author allows the work
to be copied and redistributed. Most new works of IF these days are
freeware, which means that they're
distributed for free but the authors retain copyright and place
some restrictions on redistribution; this field is meant to provide
some guidance, in general terms, about the author's copying rules.
This field's value should be chosen from the following keywords:
- Prohibited if no copying or redistribution of any kind is allowed
- No Restrictions if the game may be copied without restriction
- No-Cost Only if the game may be redistributed but only with absolutely no fees to recipients;
- At-Cost Only if the game may be redistributed with a maximum charge to recipients of the actual cost of the physical distribution, such as media, mailing, or connection charges, but with no profit or other benefit to the distributor;
- Nominal Cost Only if the game may be redistributed for a small charge to recipients to cover the actual cost of the physical distribution and some small compensation to the distributor for the work involved in providing the distribution;
- Other for rules that don't fit into any of these categories.
In addition to the keywords above, one of the keywords "Compilations Prohibited" or "Compilations Allowed" may be added, after a semicolon, to indicate whether or not the game may be distributed as part of a group of freeware and shareware games compiled by a third party, such as a compilation CD offered for sale or included with a magazine. Like the LicenseType field, this field provides guidance only and is not definitive: users must consult the license text that accompanies the game to learn the author's full, official copying rules.
PresentationProfile
Format: Text
Example: PresentationProfile: Multimedia
TADS 3 versionInfo example: presentationProfile = 'Multimedia'
The name of the recommended "presentation profile" for the game.
This is a hint that gives the run-time interpreter an idea of the style
of the game's user interface; interpreters can use this information to
choose the most appropriate display settings, such as fonts and
colors. Interpreters need not use this information at all; it's
purely advisory.
This value can be a user-defined profile name, or one of these pre-defined values:
- Plain Text indicates that the game is entirely text, with no graphics and with text formatting limited to "highlighted" text (i.e., the traditional TADS 2 highlighting, which is usually rendered as bold-face or equivalent).
- Multimedia indicates that the game makes use of HTML text formatting effects (such as fonts, text colors, text sizes, italics, and tables) and/or displays graphics.
- Default isn't a true profile, but rather explicitly selects the default profile. Some interpreters let the user choose a particular profile as the default, in which case this will select that profile.
Authors can, if they wish, specify custom profile names of their own creation here, but authors doing so are advised that (1) interpreters will not generally be able to infer anything from profile names other than ones defined here, and (2) other standard profile names may be added here in the future, so custom names that authors choose could conceivably collide with future additions.
The profile name isn't sensitive to case (that is, "multimedia" is treated as equivalent to "MULTIMEDIA"). However, we recommend that if you're using one of the pre-defined profile names listed above, you should use the exact capitalization as shown.
In practical terms, the presentation profile is used by some interpreters to select a default set of visual settings to use when starting the game. For example, HTML TADS for Windows looks for a "theme" that has the same name as the presentation profile, and uses the matching theme, if any, when starting the game. An HTML TADS theme is simply a set of font, color, and other visual settings. Other interpreters, including all of the current text-only interpreters, completely ignore the presentation profile setting. Authors mustn't expect a presentation profile to select any particular color or font scheme or to have any other specific effects, because it's up to each interpreter to determine how to use the profile setting, if at all.
Note that the presentation profile does not have any effect at all on the capabilities of the interpreter: the profile setting doesn't turn off any features an interpreter would otherwise offer, and it doesn't limit what kind of interpreter can be used to play the game. Selecting the "plain text" profile, for example, does not disable graphics or sound in an interpreter; it simply gives the interpreter guidance that the author feels the game will look best when displayed in a style (fonts, colors, etc.) suitable for traditional text-only games. Similarly, selecting the "multimedia" profile doesn't prevent the game from being played on text-only interpreters; it merely hints to interpreters that they should use a visual style suited for a more diverse mixture of text effects and/or graphics.
Every TADS game should have an IFID - an "Interactive Fiction Identifier." This is a universally unique identifier (a "UUID," in the sense of ISO/IEC 11578:1996). Essentially, it's just a very large number that's assigned to the game to identify it unambiguously. No other game - by any author, using any authoring system, on any planet in any galaxy for all of eternity - should ever use this same number. (When we say "universally" unique, we really mean it.)
The point of the IFID is to identify the game unambiguously, so that different programs can communicate about a game and be absolutely sure that they're talking about the same one. For example, a game browser on your PC might want to contact the IF Archive to request the latest copy of a particular game; it could do this by sending the IFID to the Archive, and the Archive would know exactly which game your browser is talking about.
This kind of eternal galactic uniqueness might sound difficult to come up with, but the laws of probability and statistics actually make it pretty easy. As it turns out, all you have to do is pick a big enough random number. The more digits you pick, the less likely it is that someone could ever randomly pick the same number. If you pick enough digits, you can get the odds down to effectively zero.
TADS IFIDs use the industry-standard UUID format. This is simply 32 random hex digits, written out like this: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
Selecting an IFID is just a matter of picking 32 random hex digits and putting them in the UUID format. For your convenience, tads.org provides an on-line IFID generator - just go to that page, and it'll automatically roll up an IFID for you to use.
There are a few rules about IFIDs that you should be careful to observe.
Every game should have an IFID. You should generate a new IFID for each new game project you start. Note that TADS Workbench for Windows does this automatically for you when you use the New Project Wizard. (This feature is available starting in Workbench versions 2.5.10 and 3.0.10.)
Each game should have a unique IFID. This is particularly important if you're using an existing game as a template for your new game, by copying the core files from one of your older games. If you do this, be sure to create a new IFID for your new game - don't just "inherit" the IFID from the game you used as your starter template.
Pick an IFID randomly. Don't pick your IFID's digits by hand to make some pattern you like. If everyone started picking out "vanity IFIDs," the chances of collisions would increase dramatically, because a pattern that's pleasing to one person is likely to please lots of other people just as well. Yes, yes, we understand that every 128-bit number has equal probability in a uniform distribution, so don't start lecturing us on the difference between typical and random, and all that. But the key is a uniform distribution: if people start choosing numbers by hand, we'll have anything but. So use a good random-number generator, such as our on-line IFID generator.
Use a single IFID throughout a game's entire lifecycle. Never change the IFID once you've started a game (or at least, not after you've released it). Even if you release an updated version of your game, use the same IFID. The IFID is meant to represent the game across all of its versions, so that archivists will be able to tell that any separate versions floating around are all different editions of the same work.
For pre-IFID games, use an MD5 hash. If you're updating a game you released without any GameInfo data, or without an IFID value, there's a "default" IFID defined for it: an MD5 hash of the .gam or .t3 file, written as "TADS-xxxx", where 'xxxx' is the 32 hex digits of the MD5 hash value, with no hyphens or other separators within the hex digit string. Note: tools are forthcoming that will provide you with the correct MD5 hash code for a pre-IFID game automatically. Before you release your update, you should go back to the original released version (preferably the one you uploaded to the IF Archive) to determine this default IFID, and use it as the explicit IFID value in the new version - and, of course, for any future updates.
If you've already released several different versions of your game without IFIDs, calculate the default MD5 IFID for each of them, then put all of these IFIDs in your IFID field, separating them with commas. (The reason to specify all of the past default IFIDs is that it allows archivists to relate all of the past works to the new update.)
One of the features of the Treaty of Babel system is an option to include "cover art" with a game. The idea is that you can include an image that game browsers can display to represent your game - sort of a virtual cardboard box cover.
You can do this in a TADS game simply by including a multimedia resource called ".system/CoverArt.jpg" or ".system/CoverArt.png". You should only include one or the other, and the file format must match the name - that is, if you call it ".system/CoverArt.jpg", it has to be a JPEG image, and if you call it ".system/CoverArt.png" then it has to be a PNG image. Use the TADS resource compiler to embed the image; use the exact resource name ".system/CoverArt.jpg" or ".system/CoverArt.png", with no other path prefix.
The Treaty places certain requirements on the image, and you should read the Treaty for the full details. Here are the basic parameters, though: the image must be at least 120x120 pixels, and it should be no larger than 1200x1200; 960x960 is the preferred size; and the image should be roughly square. You can use any color depth or other variation that's valid in your chosen format.
The simplest way to add game information to your compiled game file is to create a text file called "GameInfo.txt" using your favorite text editor. Make this a plain ASCII file - don't use any "extended" characters, such as accented letters or curly quotes.
(If you really must use characters outside of plain ASCII, you can, but it's a little more complicated. In particular, you must encode the file in the character set known as UTF-8 if you use any non-ASCII characters. Many text editors can do this automatically, but you usually have to use a special option or command. For more details on UTF-8 in general, see below.)
Here's the general format of the file:
Name: Value Name: Value ...
That is, you put a name/value pair on each line by starting with the name, followed by a colon, followed by the value string. For example:
IFID: c583a1d0-c809-11da-a94d-0800200c9a66 Name: My Sample Game Byline: by J. Random Author AuthorEmail: J. Random Author <random@ifauthor.org> Desc: My first sample game! Version: 1 FirstPublished: 2006
Next, you compile your game as normal, to produce a ".gam" or ".t3" file.
Finally, you have to use the appropriate TADS Resource Compiler to combine your compiled game file with the GameInfo.txt file. On most platforms, the Resource Compiler is called "tadsrsc" for TADS 2, and "t3res" for TADS 3. The TADS documentation for full details, but here's the basic command line format you'd use for each TADS version:
- TADS 2: tadsrsc mygame.gam -add GameInfo.txt
- TADS 3: t3res mygame.t3 -add GameInfo.txt
Note that you must run this resource step after you compile your game, and you have to do it again each time you compile. You must repeat the resource step after each compilation because the compiler creates a brand new .gam or .t3 file each time you compile, overwriting the combined game-plus-resource file. Of course, you don't have to re-create the GameInfo.txt file itself on each compilation - you only have to run the resource step again each time.
This approach has the drawback that you will need to edit the file manually to keep it in sync with your game - this is especially error-prone for things like the version number and release date. So, you might wish to use an automated approach, which is slightly more complicated to set up but which is probably less trouble in the long run. We provide recipes for setting up an automated build procedure for TADS 2 and for TADS 3 below.
The procedure we outline here lets you generate the GameInfo.txt file automatically whenever you compile your game for release. This is nice because it means that you can use the same dynamic information you have in your game's source code to generate your GameInfo.txt data.
If you'd prefer to create your GameInfo.txt file manually, see above.
Note that if you use this automated approach, you must restrict yourself to plain ASCII text in the GameInfo.txt file, because TADS 2 doesn't have any way to convert text to Unicode when writing to a text file. If you want to use any characters outside of the plain 7-bit ASCII range (for example, if you want to use any accented letters), you'll have to resort to the manual procedure described above, and you'll have to use a text editor that can write UTF-8 files.
Step 1. Find the gameinfo.t module in your TADS directory - this is one of the standard system files distributed with the TADS compiler. Add a #include line for this file in your game's main source file. Important: if you #include the file std.t in your game, include gameinfo.t before std.t. A typical game's source file might start off like this:
#include <adv.t> #include <gameinfo.t> #include <std.t>
Step 2 - for TADS Workbench users only. (If you're not using TADS Workbench on Windows, you can skip this step.) Open your game in Workbench, and then click the "Settings" item on the "Build" menu. On the "Source" page of the Build Settings dialog, click on the "Compiled game file (.gam)" item in the "Graphics and Sound Resource files" list box. Click "Add File", then type "GameInfo.txt" into the filename text box and click "Open".
(Optional) If you want to include a Cover Art image, first create your image, saving it in either JPEG or PNG format (you must use one of these formats). Open the Build Settings dialog and go to the Special page. Enter the name of your image file in the Cover Art text box. (Note that this only works in Workbench release HT-13 and later; in earlier versions, you must use the manual procedure outlined below.)
Step 3. Define a function called getGameInfo in your source file. This function takes no parameters, and returns a list. The list consists of pairs of strings; the first string of each pair is the name of a parameter, and the second of the pair is the value for the parameter. Here's an example:
getGameInfo: function { return ['IFID', '6b8ed850-c80b-11da-a94d-0800200c9a66', 'Name', 'My Test Game', 'Byline', 'Bob I. Fiction', 'Desc', 'My simple test game, just to demonstrate how to write game information.']; }
Step 4. This step is necessary only if you're not using the standard preinit function defined in std.t. In your preinit function, add the following line of code at the very beginning of the function:
writeGameInfo(getGameInfo());
Step 5. Compile your game. You must compile for release (i.e., not for debugging) in order for preinitialization to run during compilation - if you compile for debugging, the GameInfo.txt file won't be created until you actually run your game.
Step 6 - for command-line compiler users only. (If you're using Workbench for Windows, you can skip this - Workbench will perform this step for you automatically because of the way you set things up back in Step 2.) Run the TADS Resource Compiler (tadsrsc) and bind the generated GameInfo.txt file into your game:
tadsrsc mygame.gam -add GameInfo.txt
(Optional) If you want to include cover art in your game, save your image as either a JPEG or PNG image. On the tadsrsc command line above, add an entry for your image to the end of the command, after GameInfo.txt, like this:
image.jpg=.system/CoverArt.jpg
Replace "image.jpg" with the actual name of your file, but leave the rest exactly as shown. If you saved your image in PNG format instead of JPEG, change the ".jpg" at the end to read ".png" instead. The "=" sign says that you want to give the file the special name ".system/CoverArt.jpg" (or .png) in the resource catalog - the catalog name has to be exactly as shown for tools to recognize its special purpose.
That's it! Your game information is now stored in your compiled game file.
The procedure we outline here lets you generate the GameInfo.txt file automatically whenever you compile your game for release, which is nice because it means that you can use the same dynamic information you have in your game's source code to generate your GameInfo.txt data. This approach will also save you the trouble of finding a text editor that can handle UTF-8, because TADS 3 is perfectly happy to do the character set conversion work for you automatically.
If you would prefer to create your GameInfo.txt file manually, see above.
Note: this procedure assumes you're using the standard TADS 3 adventure game library (known as "adv3"), since it depends on some classes defined in the library.
Step 1 - for users of TADS Workbench for Windows only. (If you're not using TADS Workbench on Windows, you can skip this step. If you created your project using Workbench's "New Project" command, you can also skip this step, because Workbench will have already done it for you.) Open your project in Workbench, and right-click on "Resource Files" in the project window; this will open a standard Windows file selector dialog. Make sure the file selector is showing the directory containing your project (your .t3m file) - if not, navigate to your project directory. Type "GameInfo.txt" into the filename box and click the Open button. (It doesn't matter if this file doesn't exist; your game will create it automatically during pre-initialization.)
(Optional) If you want to include cover art, save your cover art image as either a JPEG or a PNG file (you must use one of these formats). Go to the Project window, open the Special Files section, and find the item labeled Cover Art. Right-click this item, then select "Set File..." from the pop-up menu. This will bring up a file selection dialog; simply select your image file.
Step 2. Create an object of class GameID to describe your game. The GameID class is described in detail in the TADS 3 library file modid.t; the quick summary is that this class lets you define some descriptive information for your game, which the library uses to generate the GameInfo file automatically. The library also uses the GameID information for other purposes, such as the VERSION command. If you're using Workbench for Windows, and you used the "New Project" command to create your game, Workbench will already have created a placeholder for this object in your game's main source file, so you merely need to find the placeholder object and edit its property values. Here's an example of how this object should look:
versionInfo: GameID IFID = '64d2c120-c80b-11da-a94d-0800200c9a66' name = 'My Test Game' version = '1.0' byline = 'by Bob I.\ Fiction' htmlByline = 'by <a href="mailto:bob@if.com">Bob I.\ Fiction</a>' authorEmail = 'Bob I. Fiction <bob@if.com>' desc = 'My simple test game, just to demonstrate how to write GameInfo data.' htmlDesc = 'My simple <b>test game</b>, just to demonstrate how to write <i>GameInfo</i> data.' ;
Step 3. Compile your game. You must compile for release (not for debugging) in order for preinitialization to run during compilation - if you compile for debugging, the GameInfo.txt file won't be created until you actually run your game.
Step 4 - for command-line compiler users only. (If you're using Workbench for Windows, you can skip this - Workbench will perform this step for you automatically because of the way you set things up back in Step 1.) Run the T3 Resource Compiler (t3res) and bind the generated GameInfo.txt file into your game:
t3res mygame.t3 -add GameInfo.txt
(Optional) If you want to include cover art in your game, save your image as either a JPEG or PNG image. On the t3res command line above, add that filename at the end of the command, after GameInfo.txt, but list it like this:
image.jpg=.system/CoverArt.jpg
Replace "image.jpg" with the actual name of your file, but leave the rest exactly as shown. If you saved your image in PNG format, change the ".jpg" at the end to ".png" instead. The "=" sign says that you want to give the file the special name ".system/CoverArt.jpg" (or .png) in the resource catalog - the catalog name has to be exactly as shown for tools to recognize its special purpose.
That's it! Your game information is now stored in your compiled game file.
Adding more keys
When you define your versionInfo object as shown above, here's what's really going on internally: at pre-init time, the library looks for certain property names in your versionInfo object, and writes their values to the "gameinfo.txt" file using the associated keys. The library creates the gameinfo.txt file itself, so you don't ever need to edit this file directly. In fact, you can't edit it directly even if you wanted to, because any changes you make would be lost the next time you compile - the library overwrites the file with its automatically-generated copy on every build.
Since you can't edit gameinfo.txt directly, you might wonder how you go about defining key/value pairs other than those we've shown in the example above.
The first thing to do is to look at the list of standard name/value pairs above. For each one, notice that there's a "TADS 3 versionInfo example" listed. That shows you the format to use for that name/value pair. So, if you can find the key that you want to use in the standard list above, just add it to your versionInfo object as shown.
If you can't find the key you're looking for in the list above, either because the key was added to the list since the last time we updated this article, or because you want to add a custom key rather than a standard key, you have to perform an extra step. What you need to do is to add a mapping from a versionInfo property name to your new GameInfo key name. To do this, you simply override the metadataKeys property of your versionInfo object to add your new key. The metadataKeys property contains a list of alternating GameInfo key names and versionInfo property IDs. Each pair creates one association, so you just need to add one pair for each new key you want to use.
For example, suppose you want to use a custom key called "kids.age-range". You could accomplish this like so:
versionInfo: GameID metadataKeys = (inherited + ['kids.age-range', &ageRange]) ageRange = '5-11' IFID = '64d2c120-c80b-11da-a94d-0800200c9a66' // etc with the same definitions as before... ;
We've overridden the metadataKeys property, first inheriting the default value and then adding in our new key-name-to-property association - specifically, we've associated the custom GameInfo key called "kids.age-range" with the versionInfo property ageRange. Once we've done that, we can set the "kids.age-range" value simply by setting the property we've associated with it.
For full details on how the versionInfo object works, you should look at its Adv3 library superclasses: in particular, its immediate superclass, GameID; and that class's superclass, GameInfoModuleID.
In April of 2006, the designers of several of the most popular IF systems agreed on a scheme that will give tool writers a standard way to extract bibliographic data from games generated by any of the participating systems. The standard is known as the Treaty of Babel, and it defines a common metadata format called the iFiction format.
Each of the different IF systems has its own private story file format, and the Treaty makes no attempt to unify these formats. Instead, the Treaty simply specifies what each system must provide, not how it provides it. Each system therefore defines its own mechanism for storing the information. In the case of TADS, that mechanism is the GameInfo format.
The Treaty's common interchange format - the iFiction format - uses XML to represent the information. GameInfo, of course, isn't XML-based. Fortunately, the GameInfo format captures all of the needed information, so producing an iFiction record from a GameInfo record is a relatively straightforward format conversion that can be easily automated.
In a future version of this specification, we'll lay out the exact mapping from GameInfo to iFiction here. For the moment, we use that time-honored software development methodology, the "specification by implementation": specifically, we define the mapping as exactly what's implemented in the TADS module in the Babel Software Suite. Most of the mapping is obvious, and inspection of the source code should clear up the few bits that aren't.
Note that, as of this writing, the Treaty is a "beta" version, so some of the details are subject to change. (That's one of the reasons we're holding off for a bit on a thorough specification of the GameInfo-to-iFiction mapping.)
Anyone may add their own custom name/value pairs, to store additional information beyond what's in the pre-defined standard set. If you wish to define your own custom entries, you must use names that contain one or more periods ("." characters). By design, standard names do not and will never use periods; using periods in third-party names ensures that third-party names will never collide with any standard names that might be added in the future.
The periods are meant to delineate "namespace" prefixes: the part of a name up to its last period is considered a namespace identifier, which indicates that the name isn't part of the standard set but belongs to a set defined by some third party. The namespace identifier is arbitrary, but we recommend that you pick something descriptive of the group of name/value pairs you're adding. For example, a group of writers creating games especially for children could create a "kids" namespace, adding name/value pairs like "kids.age-range" and "kids.educational".
Given the relatively small community actively writing IF, the chances of two people picking overlapping namespaces seems small. Even so, we make this offer: if you'd like to register a namespace, let us know (see the tads.org website for contact information), and we'll add your namespace to the following reserved list.
List of reserved namespaces: There are currently no reserved namespaces.
The GameInfo.txt resource must be encoded in UTF-8, which is a character encoding defined by an international computing standard. UTF-8 encodes all of the characters in the Unicode (ISO 10646) character set, using a varying number of bytes per character.
If you're using plain ASCII text, it turns out that your file is already in UTF-8. The UTF-8 encoding is designed so that each ASCII character is encoded in UTF-8 exactly the same way it is in ASCII. This means that you can use your regular text editor to prepare your file, save the file as plain text, and use the result directly as your GameInfo.txt file - you won't need a Unicode text editor or any conversion tools. However, this applies only to the plain ASCII character set, which is the set of character codes from 1 to 127; if you're using any special characters, such as accented letters, you're actually not using plain ASCII, so you'll need to convert the file to UTF-8.
UTF-8 has become widely used on the internet, so many text editors and other utilities support this format. If you need to create a GameInfo.txt file manually, you should be able to find a text editor or word processor for your platform that can save files using this encoding. You'll probably have to use a special command to tell your editor to do this, so check your editor's documentation - try searching your editor's on-line help for "utf8" or "utf-8".
For full information on UTF-8 and Unicode in general, you can check the Unicode web site.
The GameInfo metadata for a game is stored inside the compiled game file (".gam" for TADS 2, ".t3" for TADS 3), using the standard TADS multimedia resource system. The game information is always stored as a resource called "GameInfo.txt", with no path prefix. Refer to the TADS 2 and/or TADS 3 compiled file format specifications for details on how multimedia resources are embedded in these formats.
The contents of the GameInfo.txt resource must be text encoded in the Unicode UTF-8 standard format.
Note: plain ASCII text is a subset of UTF-8, so no special encoding is required for a GameInfo file containing only 7-bit ASCII characters (that is, characters from code points 0 to 127).
The text in the file consists of zero or more lines of text, separated by any of the common newline sequences (CR, CR-LF, LF-CR, or '\u2028', where CR is '\u000D' and LF is '\u000A', and '\u2028' is the Unicode line separator character). Each line is in one of the following formats:
- Blank or all whitespace. A line with no text other than whitespace characters is ignored.
- # comment text. A line starting with a pound sign ("#") is a comment line, and is ignored.
- Name: Value. A line starting with a name, which is a sequence of ASCII characters (in the range '\u0020' to '\u007f') followed by a colon, is a name/value pair definition. The value portion can contain any Unicode characters other than newline sequences.
- whitespace Value-continuation. A line which starts with one or more whitespace characters followed by a non-whitespace character is a continuation line, as long as the line immediately follows a name/value pair line or another continuation line. This means that it is considered to be part of the previous line: it is logically appended to the previous line, after replacing the newline separating the two lines and all of the leading whitespace on the continuation line with a single space.
The standard set of Name/Value pairs is defined in a separate section.
A given name may appear zero or one times in a GameInfo resource. That is, every name is optional: a tool reading a GameInfo file must not require any particular name to appear, so it cannot consider a GameInfo resource invalid because it lacks an entry of a given name. In addition, a given name cannot appear more than once in a GameInfo file; there can therefore be at most one value for each name.
The Name strings are insensitive to case. For example, the Name string "Byline" is considered equivalent to "BYLINE" or "byline" or "ByLine". This means that you can write Name strings in any mix of upper and lower case that you like when preparing a GameInfo file, and it means that parsers must ignore case in Name strings when parsing a file.
Similarly, if the Value for a particular Name is specified as coming from an enumerated set of possible values, the enumerated set is to be considered insensitive to case, unless stated otherwise in the specification for that particular Name/Value pair. Parsers should nonetheless preserve the exact case of Value strings as given if storing or displaying the strings, since many of the Name/Value pairs are designed to have human-readable values, and a human reader would expect to see the exact strings as originally prepared by the creator of the GameInfo file.
A tool reading a GameInfo record must ignore any names it doesn't recognize - that is, a tool must not treat an unrecognized name as an error. This ensures that new standard name/value pairs can be added in the future without breaking existing tools.
Here's a full example, with the most important fields filled in.
# Sample game information for Ditch Day Drifter Name: Ditch Day Drifter Byline: by Michael J. Roberts HtmlByline: by <a href='mailto:not-my-real-address@not-a-site.net'> Michael J. Roberts</a> AuthorEmail: Michael J. Roberts <not-my-real-address@not-a-site.net> Desc: You're an undergrad at Caltech, where you wake up to find it's Ditch Day, the day when the seniors ditch classes and leave "stacks" for the underclassmen to solve. The original TADS sample game. HtmlDesc: You're an undergraduate at Caltech, where you wake up to find it's Ditch Day, the day when the seniors ditch classes and leave “stacks” for the underclassmen to solve. <i>The original TADS sample game.</i> Version: 1.0 ReleaseDate: 1990-08-10 Language: en-US LicenseType: Freeware CopyingRules: Nominal Cost Only; Compilations Allowed PresentationProfile: Default
Archive maintainers and others who wish to extract game information programmatically can download gameinfo.zip, which contains some simple utility routines that extract the game information records from a game file. These routines make it easy to find and parse the GameInfo metadata in any TADS 2 or 3 compiled game - they take care of parsing the compiled game format, finding the GameInfo resource, and parsing the contents of the GameInfo into individual name/value objects. You can use these routines in your own programs that manage IF story files. Feel free to contact us if you need any help using this code.
The Babel Software Suite is the reference implementation of the Treaty of Babel. The Babel software includes a TADS module that reads GameInfo records from TADS 2 or 3 games and presents them as iFiction metadata.
Version 1.0: The first version of the GameInfo specification was published in August, 2002.
Version 1.1: This udpate was released in preliminary format in April, 2006, and officially published in August, 2006. This version is the same in all of the fundamentals as 1.0; the only change is the addition of several new name/value pairs in the standard set. All of the new name/value pairs were added to improve interoperability with the iFiction metadata format. It also adds the Cover Art resource.
Version 1.2: This update was released in January, 2007. In this version, the Cover Art resource name (introduced in v1.1) is changed to include the path prefix ".system/".