Skip to content

Latest commit

 

History

History
284 lines (240 loc) · 12.5 KB

File metadata and controls

284 lines (240 loc) · 12.5 KB

The text system, and the generators

Liberation does not store its prose. It stores a program that writes its prose, and both the source and the compiled form of that program shipped on the disc.

The nine text files

File bytes form what it is
PGE.txt 16,304 source, with comments the plot / news generator
dte.txt 14,136 source, with comments location descriptions
ObjText.txt 16,658 source, with comments skills, weapons, body parts, objects
cte.txt 17,809 compiled character text
dossier.txt 4,849 compiled the police-dossier template
Char1/char1.txt 89,596 compiled 566 lines of character dialogue
shop1/shop1.txt 108,229 compiled 601 lines of shop dialogue
newChar/NewChar.txt 74,932 compiled 71 lines of character creation
EndGame/EndGame.txt 1,003 compiled the ending conversation

endgamet/endgamet.txt is byte-identical to EndGame/EndGame.txt (SHA-1 794661220d26…).

The compiled form

A record is

0xD7   UWORD id   UWORD length   '[' ... ']'

where length counts from the [ to the ] inclusive, plus one, padded to even; 0xD7 0xFFFF 0x0000 closes a nested block. Records nest: a record of length 440 contains five records of its own.

Inside a record, the ASCII caret ^ introduces an opcode — the same introducer the source files use, so the "compiled" form is only half compiled — | separates alternatives, [ and ] bracket blocks, and 0xB1 followed by a 16-bit index plays a speech clip — the index being exactly the entry number in the .LOG beside the directory's .SAM files (section 10). So the dialogue script and the speech index are the same numbering, and a 0xFFFFFFFF in the .LOG is a line the actor never read.

The end of EndGame.txt, decoded:

D7 0012 0032 [ B1 0000 "Don't lose interest now. Get me out of here!" ]
D7 0014 01B8 [ ^X=K0 ^X=H21 ^X=I1
    D7 0000 002A [ ^X=G0 ^XSI ^XS!65520 ^X+I1 ^XIK=0 [ ^XG0 | ^XG-1 ] ]
    D7 0001 0012 [ B1 0001 "Who are you?" ]
    D7 0002 0069 [ B1 0002 "I guess so, though I was beginning to think I
                            might not make it. How did you find me? Who
                            sent you?" ]
    D7 0003 001F [ B1 0003 "I can't thank you enough!" ]
    D7 0004 00C8 [ B1 0004 "I hope so - I'd hidden it well before they got
                            me... Will you get it to the Emperor?" ^X=K1 ]
    D7 FFFF 0000 ]

and one record in the file is not dialogue at all:

D7 270F 0000 [ The rights of Kim Blake and Ross Goodley to be identified as
               authors of the text of this work are hereby asserted in
               accordance with the Copyright Designs and Patents Act 1988. ]

A copyright assertion compiled into the text stream as though it were a line of dialogue, naming Kim Blake as the writer. It is in four of the nine files — char1.txt, shop1.txt, NewChar.txt and EndGame.txt — and in the first three it is record id 0, length 178, the very first record in the file, while in EndGame.txt it is record id 9999, length 0, at the end. Same 168 characters, opposite ends of the file, two different ids: whoever compiled them did it twice, differently. Kim Blake is a third name on the disc and appears nowhere else on it — not in the game's $VER:, not in a file name, not in the ISO fields.

The source form, and the note to the translators

PGE.txt opens with 2,255 bytes — 384 words over 70 lines — that were never meant to be pressed. They are a manual for the text-generation language, addressed to the people who would translate it, on a retail disc:

 **********    Notes for translators........

	The following text is a source text, from which a final text is
generated. Therefore it contains a lot of control information, which while
not irrelevant to your task may be safely ignored, as i can reformat your
translation later as necessary. ...

^On[ option 1 | option 2 | final option ]
	Randomly selected optional words or phrases.
	If you could manage this piece of formatting I should be very grateful.

^Nx-y
	Generates a random number between x and y. Observe the necessary
	word order of the target language, but otherwise leave alone.
^S
	Instructs the processor to process a subroutine (marked by * ).
^^
	Instructs the processor to insert a carriage return into the
	final text. Use this as a paragraph separator.
^*
	Never ever allow this character string to occur.
^J
	Generates a random profession
^P
	Generates a personal name
	...
	The information above is incomplete but I hope will serve to
give you some idea of what is going on. I am aware that at first sight this
piece of text looks nightmarish and so would suggest that if you cannot
make anything of it you phone me direct on (0742) ###-### and I can talk you
through it.
	Thanks for your efforts,
		Ross Goodley
P.S. Don't worry about agreement for case,number and gender with randomly
generated nouns. I can sort that out later.

********  End notes for translators

The subscriber digits are redacted here; the dialling code is not, because it is evidence. 0742 was Sheffield, and it stopped existing on 16 April 1995 when PhONEday moved Sheffield to 0114. So the note was written on or before that date by somebody in Sheffield — which is where Byte Engineers were.

Nothing on the disc uses the German or French the note anticipates. The two fonts carry twenty-three accented Latin capitals that no shipped text prints (section 08), the name generators carry German surname fragments and Japanese romaji, and this note is the third witness: a localisation was planned in detail and did not ship.

The language itself

From the notes and from the files, the control set is

^On[ a | b | c ] pick one of n at random
^Nx-y a random number between x and y
^In=v[ a | b ] test a variable
^Lx-y[ ], ^E>n[ ], ^G[ ] more tests
^FSxx, ^FTxx, ^FXxx set and test state flags
^S<letter> call a subroutine
*<letter>, ~<letter> define a subroutine
@Cc, @Vv insert previously generated text: the city's name, the victim's name
^J, ^P, ^W, ^Z, ^A generate a profession, a personal name, retrieve elsewhere
^^ paragraph break
^; comment to end of line
^{n text} define object n

The comments left in the source are a designer's working notes:

^; Case of A=0-6...A=0 Normal node
^; A=1 Occupant is dead
^; A=3 Attack
^; A=5 Dead + Attack
^;---Clue text begins here.....horrid business!---
^;a good path exists else skip to '|'
^;--- Flag E set means...
;General purpose items
;Hacker Items Subroutine
;ShadowRunner items subr
; corporate executive items

What the generators generate

PGE.txt is a news-report generator. One sample branch, with the alternatives left in:

^O2[Violent encounters|Angry exchanges] between security forces and members
of the Prisoners of Conscience movement have been
^O2[occurring all|continuing throughout the] day
^O2[outside|within the grounds of]
@Cc ^O3[City Hall|Penitentiary|Government Buildings].

and its item tables are the whole loot economy, with a security rating per object:

*G  general    gold ring / antique timepiece / bag of electronic components
               / TriDee set / massage parlour account card
*H  hacker     Ice Breaker / Pocket Terminal / Records Computer protocols
*F  fixer      fake ID / stolen CredCard / RunnerTeam contact address
*R  runner     TX^N1-6/^N1-30 Grenade Launcher / patron contact address
               / ArmsCorp Super-Taser / Krupps ZZ^N12-35 Hand Blaster
*S  scholar    old book / University Library card / unpublished article by ^P
*E  executive  industrial espionage / stolen blueprints
               / ^B5-5 Corporation computer protocols / Fixer contact address
*W  worker     complete set of girlie magazines / dirty TriDee
               / GravBall season ticket / starship ticket
*P  cop        dirt on a superior / SecuriCorp computer protocols
               / details of a crime

^n0S^n4T^n5 after each item is, per the comment in the file, "store 0 string term, 'S' next byte is security rating" — ratings 0 to 7, "easy to near impossible". A grenade launcher's model number is itself generated: TX^N1-6/^N1-30.

The name and place generators are compiled into captiveII and PlotGen rather than the text files:

surname roots   $gold$grun$braun$wein$eisen$ein$bieder$jaeger$tell$fern$hahn$
                stein$mann$berg$er$mensch$tod$fisch$rhein$kurz$laben$weg$wehr$
place suffixes  $bridge$ton$ford$field$town$wick$ham$
company parts   $Info$Star$Mind$Para$Grav$Drive$Scan$Ion$Electro$Terra$Selen$
                $Tec$Light$Scape$nics$tics$sum$Technology$Logix$Land$Lon$Tron$Games$
street types    $Street$Avenue$Road$Boulevard$Lane$Park$Gardens$Gate$Crescent$
                Mews$Terrace$Drive$Alley$Approach$Arcade$Buildings$Corner$
                Quadrant$Passage$Promenade$
shop types      $*Emporium^1$*Hardware^2$*Pawnshop^3$*Gunsmith^4$*Jewellers^5$
                $*Store^1$*Market^1$*Newsagent^6$*TriDee Rental^7$
bars            $*Bar^8$*Boozerama^8$*Diner^8$*PopShop^8$*Pub^8$*Vinyard^8$
                $*Beer Hall^8$*Pool Rooms^8$*Speakeasy^8$*Gin Palace^8$
                ^cha no mise^8$^biru no mise^8$
pub names       $*Dog$Bush$*Parrot$Firkin$*Bull$Star$Frog$*Queen$*Aardvark$
                Peristalsis$&Black$&Green$King$Elephant$Castle$'s $ no $ and $The $
newspapers      $Gazette$Advertiser$News$Guardian$Times$Herald$Mercury$Mirror$
                Express$Messenger$Beobachter$Shimbun$Post$Daily News$Communique$Star$
TV channels     $Channel 2$KVLM$VidNews$NewsNet$Cable News$Terebi no Shimbun$
                NewsDesk$Fernsehnachrichten$actualites$
professions     $Governor$Councillor$Investment Counsellor$Engineer$
                Entrepreneur$Pilot$Trader$Merchant$
zones           Alpha Beta Gamma Delta Epsilon Zeta Theta Kappa
moons           Adrastea Amalthea Ganymede Callisto Himalia Lysithea Pasiphae Astraea

Three things fall out of those tables. The company generator can build its own publisher — Mind + Scape. The Jupiter-moon list is the setting. And the bar and newspaper lists are trilingual on purpose: Beobachter, Fernsehnachrichten, actualites, cha no mise, biru no mise and Terebi no Shimbun — German, French and romanised Japanese in a game whose shipped text is English. The world is supposed to read as polyglot, which is also why the fonts have accents.

And one of the surname lists is not a generator table at all:

$featherstonehaugh$patel$smythe$singh$meridew$sagan$murray$cherryh$chambers$
gaiman$cleese$simon$burkinshaw$forward$rector$alexy$jacobs$crowther$macleod$
leary$crowley$gibson$floyd$whittle$pitt$heath$goodley$chapman$palin$gilliam$
hake$turbot$

crowther and goodley — the two authors named in the game's own version string, inside the list of surnames the game gives to randomly generated citizens. Beside them: sagan, cherryh, gaiman, gibson, leary, crowley, macleod and forward (science fiction), and cleese, chapman, palin, gilliam and chambers (five sixths of Monty Python). The first-name list has Tone in it, which is what Antony Crowther is called.

The generators as programs

CityGen, PlotGen and BuildingGen are separate AmigaDOS executables that captiveII launches by name, with backup/ copies as fallbacks (section 06).

  • PlotGen reads PGE.TXT, DTE.TXT and CTE.TXT — the three source text files — and is the only one of the three that opens dos.library. It carries the newspaper, TV-channel and profession tables and the building types Library, Police Station, Private Residence, City Records Office. It also carries a base-62 alphabet (abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ$), which is what a seed or a password is encoded in.
  • CityGen 1.12, 10,824 bytes, two library calls, one relocation. It chooses which of the 33 city objects goes in which cell.
  • BuildingGen 1.3, 23,252 bytes, no library calls at all and one relocation in 23 KB — a self-contained computation handed a buffer and a seed.

So each new game runs three programs before it starts: one to lay out the city, one to lay out a building, one to write the plot, the news, the police dossier and every conversation in it out of a grammar that shipped in source form with its author's phone number attached.