Thinger is a Perl program that generates webpages which list descriptions of things from interactive fiction games. It is very similar to my previous Responser project.
The raw input data comes from several files (such as beds.json
, mirrors.json
, etc.), in JSON format, UTF-8 encoding.
All the JSON files are kept in a subdirectory called "json".
Thinger also reads an image directory to determine which cover art images it can use in the output webpages.
Thinger's output is a set of .html files, one per JSON file, plus an index.html file.
thing.json
file{
"type": "thing-name",
"supers": [ "super-name", ... ],
"icon": icon-record,
"search": [ "search-term", ... ],
"aliases": [ "alias", ... ],
"about": "introductory-paragraph",
"works": {
work-ID: work-record,
work-ID: work-record,
work-ID: work-record,
...
}
}
where:
type
is the main name of the types of things described in this file; for example: "ducks"
or "crystal balls"
. Note that space characters are permitted and that the type is usually expressed in plural form.supers
is the list of the supercategories of things that this category belongs to. For example, axes are both "tools"
and "weapons"
. This field is optional.icon
associates a graphic image with this file. See icon-record. This is optional.search
is a list of strings to search for in my walkthroughs that name things in this category. At its most basic, it should list the singular and plural forms of the word in the type
field, but synonyms and common misspellings should also be listed.aliases
is a list of aliases for this category, to be used in the big index on the index page. Most aliases should be expressed in plural form.about
is for the introductory paragraph(s) at the top of the page. This includes all the see-also bullet points. This field is optional and must be in HTML format.works
is where the bulk of the file's data is kept, with one key-value pair per work of interactive fiction
that contains an instance of the thing.
work-ID
is a unique code used by all Key & Compass projects for representing a work of interactive fiction. This is usually the first five significant letters in the work's title followed by the last two digits of its publication year, but an extra letter might be tacked onto the end if that isn't unique.{
"img": "filename",
"attrib": "attribution-statement",
"lic": "license-code"
}
where:
"ducks.svg"
. The actual image files are in the img/icons directory."CCBY3.0"
(for the Creative Common Attribution 3.0 license) or "PD"
(for Public Domain) or the license's full name.{
"title": "work-title",
"sfx": "suffix",
"year": "publication-year",
"x": "examine-verb",
"things": [ instance-record, ... ],
"dont-list": "private-explanation",
"notes":[ "private-note", ... ]
}
where:
title
is for the title of the work. There should be no HTML markup in the title field. However, the title field sometimes contains an extra "|" character to indicate where sorting should take place. Untitled works should have a title field value of "untitled|"
.sfx
, the suffix field, is an optional field for a disambiguation phrase to go after the title. Don't put brackets around the value; let the Thinger program do that.year
is an optional field to indicate the work's publication year. This is usually unnecessary because the ID already indicates the publication year.x
is an optional field used for those games that don't understand "x" to mean "examine". The value of the "x" field should be what that game's version of examine command is. For example, Zork I didn't use "x" for "examine", so for that game's things, the value of the "x"
field should be "examine"
.things
is list of instance-records, one record per thing in the game I want to document.dont-list
is an optional field tell my QC and Suggest programs to ignore this work for this category. The value of the field is a private explanation that reminds me why I'm ignoring and skipping over it. Like, maybe the "fountain" that Suggest found is actually a fountain pen.notes
is an optional field for me to add a list of general comments about the work in the file.A work-record should have exactly one of dont-list
or things
defined, but not both.
{
"name": "item-name",
"type": "thing-type",
"loc": "item-location",
"desc": "item-description",
"list-as": "list-as-code",
"for": "for-name",
"note": "public-note"
}
where:
name
is the thing's name, as the user would type it (eg: "my bed"
, not "your bed"
), without leading articles (a, an, the).type
is the thing's type, such as "beds"
or "mirrors"
. (Yes, this duplicates the value at the top of the file; it exists in case I ever want to rearrange the data by work. I suppose I should drop it from instance-records in the future.)loc
names the initial location of the thing in the work, or where the player first sees it. On rare occassions where I want to name more than one location, those locations should be separated with semi-colons.desc
is the description of the object, as displayed when the player types examine thing.
<ins>
tags to markup internal comments/instructions/variables."list-as":"default"
instead; see below.list-as
is an optional field for things that don't have a useful response message for some reason. Each instance-record should use either a desc
or list-as
field, but not both. The list-as-code
must be one of the following:
cameo
= The thing only exists between turns and is never there for the player to examine.default
= The work's response to examining the thing is a default response like You see nothing special about that.deflected
= The work clearly has such a thing and supports examining, but it won't let you examine this thing, insisting you do something else instead or ignoring your command.empty
= The work's response to examining the thing is nothing, just whitespace or a period, indicating that the author probably wanted to write a response but never did.no-examine
= The work has an instance of the thing but doesn't support examining things.synonym
= The noun is used as a synonym for a larger object or for a group of objects. For example, "toilet" may be understood but only as a synonym for a more general bathroom fixtures object.unimportant
= The noun is understood but otherwise not implemented. The work's response will be something like That is unimportant or You don't need to worry about that.for
is an optional field and only used with "list-as": "synonym"
. The value of "for" should be the name of the object that "name"
is a synonym for. For example, on the dresses page, we might want to document a dress worn by Sally, but "x dress" acts like "x Sally". So you want { "name":"dress", ... "list-as":"synonym", "for":"Sally" }
.note
is an optional field for adding a note below the description on the page. This is presented in a box with a thick gold left-border. This note can contain HTML markup.This is a second program that analyzes the JSON datafiles; the "QC" stands for "Quality Control". I want to know if the data is not well-formatted or incomplete, where I'm having problems, and to make suggestions where I can improve the data. This program also taps into my main datafile for IF works, currently called gamejson.txt
, from my IFIndexer project.
qc0.html
through qc6.html
are the output reports from this program.What Thinger_QC currently reports on:
This program scans the markup versions of my walkthrough files for the search terms in my JSON files then reports a list of works of interactive fiction that should be added to each existing JSON file.
NOTE: Thinger_Suggest only datamines completed walkthroughs, not walkthroughs-in-progress.
"No fountains. Explain why."
"Cameo bartenders @ Pub. Optionally explain further."
<!-- JSON TIMESTAMP: YYYY-MM-DDTHH:MM -->
supers
field so we can now have multiple supercategories for things; for example, pianos are now both furniture and musical instruments.IF Things Last updated: 29 Jul 2023 davidwelbourn(a)hotmail*com