Stefan Wolff's UHS (Universal Hint System) page

Grokking the UHS

The UHS (Universal Hint System) is a system designed to help players who get stuck while playing (computer) role-playing or adventure games. The UHS philosophy is to show only the hints necessary for the player to become unstuck, without spoiling the fun of solving the rest of the game's puzzles. There is a wealth of UHS hint files at http://www.uhs-hints.com/ containing hints for games old and new.

This document describes, to some detail, the results of my digging into the UHS file format. I dug for several reasons:

Official UHS support is currently (May 2005) limited to Windows-boxes and Macs. An unsupported Java reader is available, but it supports only old file formats.

The UHS web interface is slow and horribly ad-ridden, and some hint files are unavailable using this interface.

I was curious.

Apart from being a resource for people curious of the inner workings of the UHS format, this document is also supposed to be the documentation for my UHS-to-HTML converter, written in May 2005, avaiable elsewhere on this page.

By no means is this meant to annoy the creator of UHS, Jason Strautman, by publishing things intended to be secrets. Contact me if you feel this is a violation.

UHS2HTML

UHS2HTML is not currently online.

UHS2HTML.pl is a Perl script, written by myself in May 2005, that converts a UHS file into a truckload of HTML files, such that the hints (and embedded images, etc) may be viewed using a vanilla web browser, one hint at a time, true to the spirit of the UHS. It supports every UHS format known to me (UHS88a, UHS91a, UHS95a, UHS96a), yet some (unimportant) features are not yet implemented. Since I've yet to encounter a UHS file containing sound, this is not yet implemented.

The syntax is:

perl UHS2HTML.pl uhsfile.uhs

This will convert the file uhsfile.uhs into a squillion HTML and PNG files in the current directory, overwriting files without warning. Use with caution!

After converting, just load in the generated file index.html into your web browser.
Beware, however, that this code is not ready for prime-time. It's merely a hack, done for my own convenience. Although standard disclaimers apply, you shouldn't worry too much: UHS2HTML won't do any harm if you know what you're (and it's) doing.

Bugs

Yes, probably plenty. Contact me (see below) if you encounter one or (even better) if you fix one. Note, however, that this is the first larger program I've written in Perl, and it shows!

UHS88a

The original UHS format (UHS88a) was developed in 1988 by Jason Strautman. UHS88a is pretty simple, and doesn't support all the bells, whistles and gongs of its younger siblings. Like these, it is based on lines (MS-DOS style, terminated by Carriage Return (ASCII 0x0d), followed by a Newline/Linefeed (ASCII 0x0a)). Strings are encrypted using a fairly simple arithmetic substitution cipher (this probably isn't the correct name, though).

UHS88a decryption

The decryption of each character of an encrypted string may be described by the following pseudocode function, which returns the ASCII value of the decrypted character when i is the ASCII value of the character in question:

UHS88a file components

A UHS88a-style file has two type of components. I'll call them links and hints.

The link

A link points to either a hint or another link. A link is defined by two pieces of information (each on its own line in the file): A label and the line number of the component this link points to. The label is encrypted using the cipher described above.

The hint

A hint points to the next hint or nowhere. A hint just consists of a single line, namely the hint itself, which is encrypted using the cipher described above.

The file structure

A UHS88a-file consists of a header, then a tree-like structure of links, followed by a list of hints. When interpreting line numbers, the four-line header is ignored, so all line numbers given in the file should be increased by four to get the actual line number within the file -- assuming that the first line of the file is line one (and not line zero).

I'll demonstrate the format using the UHS hints for the Interplay adventure game oldie "Borrowed Time" (UHS hint file available at http://www.uhs-hints.com/):

Line Content
1 "UHS", a magic marker indicating a UHS file.
2 "Borrowed Time", the main title
3 "73" the line number of the first hint (meaning line 77)
4 "143" the line number of the last hint (meaning line 147)
[end of header]
[directory tree]
5 "gHrGtGs iqrGr"="Opening Scene"
6 "23" the line number jumped to when selecting this link (meaning line 27)
[...]
25 "kIpHHtGs jH JDr apyr"="Wrapping Up the Case"
26 "69" -- this is the last entry of the main directory, since a link above linked to line 27.
27 "kDpJ Bw d Bw tG JDr wCCtqr"="What do I do in the office" (note: no question mark)
28 "73" link destination line no (meaning line 77)
29 "4w{ Bw d ryqpHr CIwv JDr JDzsy"="How do I escape from the thugs" (note: no question mark)
30 "76" link destination line no (meaning line 80)
[...]
75 "4w{ Bw d pIIryJ 3pIGDpv"="How do I arrest Farnham" (note: no question mark)
76 "141" link destination line no (meaning line 145)
[end of directory tree]
[hints]
77 This is the first hint line, as indicated in the header.
[...]
147 This is the last hint line, as indicated in the header.

From this disection, we can see that, from the main list of links (lines 5 to 26, inclusive: "Opening Scene" to "Wrapping Up the case"), we may jump to the "Opening Scene" list of links, where we may jump to the "What do I do in the office" list of hints (lines 77 to 79, inclusive).

Note the missing question marks. UHS2HTML inserts question marks whenever a link points to a list of hints, and not to a list of links. From the UHS88a files I've seen, this seems to be the convention. This may not be the canonical way of doing it, however, so you may experience missing and erroneously added question marks here and there.

New-style UHS formats (UHS91a, UHS95a, UHS96a)

For backwards compatibility (of sorts), the younger generation of UHS files has a header consisting of a UHS88a file telling users using an old UHS reader to upgrader to a newer one. This header takes different forms, but is always terminated by the line: "** END OF 88A FORMAT **".

Starting with UHS91a (I think), the format changed drastically. It was (perhaps inspired by the IFF file format) turned into a format consisting of "hunks", albeit still line-based. A hunk is defined using a line as

1234 foo

meaning "Here is a hunk of type foo, taking up a total of 1234 lines, including this one". This is nice, since software may choose to skip hunks it doesn't know how to handle or doesn't care about.

New-style UHS line numbers

Line numbers in UHS91a files and newer count such that the first line following the "** END OF 88A FORMAT **" line is line number 1. This will typically be the main subject hunk.

A new encryption format

When the UHS95a format came around (I believe), the UHS developers introduced a new form of encryption that's based on a key generated from the label of the main subject hunk. The main subject hunk typically (always?) follows immediately after the "** END OF 88A FORMAT **" marker. This label is typically the name of the game. The following snippet of pseudo code describes the generation of the key, based on the label of the main subject hunk and the three-character string k containing the word "key". I'll be using x[n] to denote the ASCII value of the n'th character of the string x, with indices starting at n=0.

text hunks

A text hunk points to some string of encrypted data beyond the main subject hunk. After the hunk header line and the hunk label line, a text hunk has a third line describing the location and length of this encrypted data string. This third line consists of four numbers:

hyperpng hunks

Each hyperpng hunk consists of the hunk header line, followed by a line containing three decimal numbers and then zero or more clickable "hotspot" definitions. The three numbers in the line following the hunk header line are:

Unknown (always zero?)

PNG file offset within the UHS file

PNG file length

Each hotspot definition consists of a line containing four numbers defining the clickable rectangle, followed by a hunk.

CRC checksum

The last two bytes of each UHS file comprise a 16-bit CRC checksum, used to protect users from reading corrupted hint files and to prevent third parties from tampering. UHS2HTML calculates the correct checksum and displays the stored one, but otherwise ignores them completely.

Access control

This resides in the aptly named incentive hunk, which is apparently an encrypted (using the "new-style" encryption described above) list of file offsets to hints restricted to registered users of the UHS hint readers. The web interface at http://www.uhs-hints.com/ is apparently not hampered by any access restrictions. Access control is not implemented in UHS2HTML.

Important

You are not allowed to publish or broadcast the converted UHS files in any way or form. Besides, the conversion of some UHS files may be prohibited. Check the file before converting.