Est. 1998 Beginner

WoS Quest Script

The QUEST scripting language of Well of Souls - Dan Samuel's freeware multiplayer RPG - a label-and-GOTO scene language where every quest in the game is a numbered script of actor commands, token tests and string variables called cookies

Created by Dan Samuel (Synthetic Reality Co.)

Paradigm Procedural; domain-specific scene and dialogue scripting with labels and GOTO
Typing Dynamic, untyped - all variables ("cookies") are strings, coerced to numbers by the math commands
First Appeared 1998
Latest Version Well of Souls Alpha 97 (installer dated 5 December 2008)

WoS Quest Script - called simply QUEST by its author - is the scripting language built into Well of Souls, the freeware multiplayer role-playing game written by Dan Samuel of Synthetic Reality Co. It is a small, blunt, unapologetically procedural language of numbered scenes, @labels and GOTOs, in which every conversation, every shop, every plot twist and every boss fight in a Well of Souls world is a short program. It has no types, no scoping and exactly one data structure - a string variable the author calls a cookie. It also has something most game-scripting languages of its era did not: a clearly specified answer to what happens when several players run the same script at once.

History and Origins

Synthetic Reality was, in Samuel’s own words on the company’s history page, “pretty much just me, Dan Samuel” - a working programmer who wrote games in the evenings, at Mpath Interactive (which, as the same page records, changed its name to HearMe in 1999), before going full-time on the games “sometime around May 2000”. Well of Souls was the project that followed his earlier Warpath games, and from the beginning it was conceived less as a game than as an engine: the demo page describes it as “a script-driven, multi-player Role Playing Game (RPG)” whose “idea is to make the design open enough that you can generate your own worlds and quests, share them with friends”.

The oldest surviving release note on the Synthetic Reality site is dated 5 April 1998, and the reference section attached to that same page already sets out the shape of the language:

Each World has a script file “quest.txt” which contains the overall information about that world. […] Then you define scenes, with optional characters who can deliver dialog and take action based upon your responses. The format of the script language is pretty basic, hopefully simple (though tedious) and don’t expect any great documentation soon.

That candour about documentation is worth noting, because it explains a common dating error. Many catalogues record QUEST as a 2000 language. But 2000 is the date of Alpha 30 (14 January 2000), the release in which Samuel, by his own account, got round to “finally writing some documentation for the individual script commands”. The language itself is a 1998 artefact; Well of Souls carries a 1998 copyright, and the engine’s scripted scenes predate the public Open Alpha, which was announced on 1 January 1999 - in a news item that opens by conceding the site announces “news items months after the fact”.

From there the language grew one release note at a time for a decade, through 97 numbered alpha releases, and then stopped. Alpha 97 - the last - was posted in December 2008.

Design Philosophy

QUEST is designed around a single unit of composition: the scene. A scene is a background image with sprite actors drawn on top of it, and a scene script is the program that stages what happens there. Everything else in the language exists to serve that: commands to place and move actors, commands to set mood (MUSIC, THEME, WEATHER, FX, BKGND), commands to hand the player items and take them away again, and a conditional apparatus for deciding which of those to do.

Three decisions give the language its character.

Tokens, not variables, carry the plot. A TOKEN is a numbered flag with a human-readable description, permanently attached to a character: “You have stolen the secret poker chip!” Because tokens are persistent and cheap, a world’s whole non-linear plot can be encoded as a set of token tests, with no need for any script to know what any other script did. The documentation is explicit that a cookie should not “do the job of a TOKEN”.

Conditions are written as signed algebra over IDs. Rather than boolean operators, IF takes a list of typed IDs joined with + and -:

IF T12+I15-S22, @label

which reads “if the host has token 12 and item 15 but not spell 22”. The ID letters cover most of the game’s state - T token, I item, S spell, C character class, E equipped item, G gold, H character age in hours, F map flag, J mission, plus bare words like ALIVE, DEAD and GS (Golden Soul). Disjunction arrived much later, in version A84, as a | separator between whole clauses; the dictionary describes evaluation as proceeding left to right and stopping at the first clause that comes up true.

The host runs the script. In multiplayer, when more than one player stands in a scene, the scene commands execute on the machine of the player hosting it, and - as the dictionary states plainly - “all IF conditionals are based on that player”. Objects that are given or taken in the scene affect everyone present. That single rule is what makes a language with no concurrency primitives usable in a shared world, and it is visible in the command set: GIVE versus HOST_GIVE versus PARTY_GIVE exist precisely to let an author choose the blast radius of an effect.

Key Features

FeatureForm
Scene declarationSCENE <id>, "<background>", SCENE, "<title>", 0, 0END
Labels and jumps@label, GOTO @label, GOTO EXIT, GOTO LINK, GOTO SCENE
Subroutines (A89+)CALL 200@foo arg, arg / RETURN val, val, arguments in arg0-arg9
ActorsACTOR <id>.<layer>, <name>, <skin>, <pose>, <x>, <y>, then SEL, MOVE, FACE, POSE
Dialogue1: Hello, my name is %0. Your name is %2. - the actor number, a colon, the line
Variables (“cookies”)SET name, "value" to write, #<name> to read; de-referencing via SET #<a>, "v"
Integer mathADD, SUB, MUL, DIV, MOD (all mutate a cookie in place)
Floating-point mathF_ADD, F_SUB, F_MUL, F_DIV, F_MOD (A90+)
ComparisonCOMPARE a, b then IF=, IF>, IF<, IF<=, IF>=, IF<>, IFEVEN, IFODD
StringsSET_LEN, SET_SUBSTR, STRCMP, STRSTR; STRLWR and NTH_TOKEN (A96+)
StackPUSH <cookie>, POP <cookie>
BitwiseAND, OR, XOR, NOT (A91+)
Player inputASK <seconds> sets yes/no flags and #<lastAsk>; Qword conditions scan the reply
Persistence beyond the playerGET_SERVER_VAR, SET_SERVER_VAR

Dialogue lines use a percent-code vocabulary rather than string interpolation: %0 is the speaking character’s name, %1 the scene host, %2 the reading client’s own name, %3 a randomly generated insult, %Rn a random number from 1 to n, %Mn the name of monster n, %L the host’s level title, and so on, with %% for a literal percent sign. Cookies are expanded before the line is parsed, which is what makes constructs like %I#<itemNumber> work - and, as the documentation warns, what makes cookies “quite powerful, and hence dangerous and confusing”.

Each world lives in its own folder with a quest.txt at the root and subfolders for MIDI, MAPS, ART, MONSTERS, SCENES and SFX. Large worlds split their scripts across files and pull them together with #include. Scenes live in a +SCENES table; the language has no imports, no namespaces, and a flat global numbering of scenes, tokens, items and spells.

A Worked Example

This is the casino script from Samuel’s own dictionary, reproduced as published:

SCENE 45, "casino", SCENE, "Casino Room", 0, 0
; Set up the mood
THEME 3
MUSIC "waltz2.mid"
ACTOR 1, "Barker", joshRoyalty, 2, 25, 90

; Check if he has already stolen the chip
IF T23, @hasStolenChip

; No, be friendly
MOVE 1, 15, 80
SEL 1
POSE 2, 3, 4
1: Try your luck, %1!
1: Our slots pay the most!
GAME 1
END

@hasStolenChip
; The player is a thief, sound the alarm!
1: Thief! %3!
SOUND "alarm.wav"
BKGND "closed.jpg"
1: Guards, come kill the interloper!
WAIT 2.3
WEATHER 9
; Bring in 3 monsters to fight the player
FIGHT 15, 15, 15
IF ALIVE, @wonFight
1: Ha! My guards made short work of you!
1: Now, get out of here!
WAIT 1.5
; Boot the player back out to the map
GOTO EXIT
END

@wonFight
1: Well, OK, I guess you're stronger than my guards.
GIVE T34
END

TOKEN 23, "You have stolen the secret poker chip!"
TOKEN 34, "You have beaten the three guards."

Everything characteristic of the language is here in thirty-eight lines: the numbered scene, the semicolon comments, the actor declared with a skin file and screen coordinates given as percentages of the window, the token test that forks the whole scene, the 1: dialogue lines with %1 and %3 substitutions, the FIGHT that hands control to the combat engine and reports back through the ALIVE condition, and the token definitions parked at the bottom of the table where the author found them convenient.

Evolution

QUEST grew by accretion, and the release notes read like a diary of a language finding out what it needs. It began with actors and dialogue. Scene decoration (BKGND, FX, WEATHER) came in January 2000. Variables did not arrive until July 2001 - three years in - when Alpha 57 introduced cookies together with arithmetic and comparison in a single release, turning a branching dialogue notation into something that could count. Indirection through cookies followed in October 2002, subroutines and a call stack in October 2005, floating point a week after that, and bitwise operators and parity tests in February 2006.

Samuel narrated the additions with a running commentary on his own design. Of the boolean operators: “Not sure if anyone would ever really NEED these.” Of IFEVEN and IFODD: “I can’t believe I added this. How lazy can a world developer be, hmm?” Of the cross-scene CALL that let a function fall through into unrelated code: “Of course, thinking like that gave us perl!”

The arc is unusual. Most game-scripting DSLs start by embedding an existing language; QUEST instead rediscovered variables, then functions, then a stack, in public, over seven years, each addition justified by a specific world author who had asked for it.

Current Relevance

Well of Souls is dormant. Alpha 97 is the final release: the download page records it as updated 5 December 2008, and a request for the installer in September 2026 still returns the same 9,855,503-byte file with a Last-Modified date of 6 December 2008. The news page stops in May 2008. Samuel had by then moved on to his day job at There Inc. - later Makena Technologies - and to the Arcadia family of smaller multiplayer toys.

What is remarkable is that the site is still up and still serving. synthetic-reality.com remains live over HTTP, the Quest Language Dictionary is still at wosquest.htm, the complete dated release notes from April 1998 forward are still split across three pages, and the installer and its patches still download. The game’s own official requirements - Windows 95 through XP “etc”, a Pentium 90, 16 MB of RAM, DirectX 3 or higher and Internet Explorer for the embedded web features - date it precisely, and no port to any other platform appears to have been published.

For a language whose only implementation is inside a Windows game binary, the documentation has aged far better than the runtime.

Why It Matters

QUEST is a good specimen of a category that is enormous in practice and almost invisible in language history: the one-game scripting language, written by the game’s author, documented in a single HTML page, and used seriously by a community of world authors to build things its designer never anticipated. There were dozens of such languages in the late 1990s shareware world, and almost none of them left a record. This one did, because Samuel wrote down every change he made for ten years and never took the pages down.

Two things about it are genuinely instructive. The first is the token model: by making plot state a flat, persistent, numbered set of flags with human-readable descriptions, Samuel gave amateur authors a way to write non-linear stories without writing a state machine. The second is the host-executes rule, which is a real answer to a real distributed-systems problem - who decides what happened? - expressed in one sentence of documentation and a handful of HOST_/PARTY_ command variants, so that a world author never has to think about it at all.

It is also a reminder of how much of the design of a small language is determined by the questions its users ask. Read the release notes in order and the shape of QUEST is legible as a decade of requests: someone wanted to change the background mid-scene, someone wanted to count monsters, someone wanted to reuse a snippet of dialogue, someone wanted a card game. Each got a command. The result is a language that is not elegant, but is exactly the size of the problem it was asked to solve.

Timeline

1998
The oldest surviving Well of Souls release note is dated 5 April 1998; the same document already describes quest.txt as the script file in which a world author enumerates monsters, spells, items and equipment and then defines scenes "with optional characters who can deliver dialog and take action based upon your responses"
1998
The 1 June 1998 notes move the experience-point and character-level matrices into the quest file "by popular demand", establishing the pattern that the script file owns the world's rules and not just its dialogue; a news item of 4 June 1998 points readers at the pre-alpha demo
1999
The Open Alpha phase of Well of Souls is announced on 1 January 1999 (the announcement itself notes the site posts "news items months after the fact"); Alpha 14 ships 10 April 1999 and by 25 July 1999 Synthetic Reality announces the game is "25 versions old". On 11 November 1999 Samuel decides Well of Souls will remain free, funded by voluntary donations
2000
Alpha 30, dated 14 January 2000, adds the BKGND, FX and WEATHER commands and - by Samuel's own description - is the release where he got round to "finally writing some documentation for the individual script commands"; POSE also gains optional extra animation frames
2001
Alpha 57, dated 14 July 2001, is the language's pivotal release: it introduces cookies (string variables addressed as #<name>, stored in the scene host's character file), the ADD/SUB/MUL/DIV/MOD cookie math commands, COMPARE with the IF=, IF> and IF< result tests, and the PARTY command
2001
Alpha 64, dated 25 November 2001, adds the MENU command for host-driven popup choices, a first pass at asynchronous events, and the LOCK opcode for sealing a scene against newcomers
2002
Alpha 70, dated 6 October 2002, adds HOST_GIVE and HOST_TAKE and - more consequentially for the language - cookie de-referencing, so that a cookie may hold the name of another cookie
2005
Alpha 89, dated 8 October 2005, gives the language real subroutines: CALL and RETURN with up to ten arguments passed and returned through the cookies arg0-arg9, cross-scene labels of the form sceneNumber@label, and a PUSH/POP cookie stack to protect callers' variables. Alpha 90, a week later on 15 October 2005, adds the floating-point F_ADD, F_SUB, F_MUL, F_DIV and F_MOD
2006
Alpha 91, dated 19 February 2006, adds bitwise AND, OR, NOT and XOR, the IFEVEN and IFODD tests, and the J conditional for mission state - a letter introduced with "Yeah yeah, I ran out of letters" and the joke that this "must mean the game is just about complete"
2007
Alpha 93, dated 4 March 2007, adds SHUFFLE, which deals a randomly ordered set of numbered cookies for card-style mini-games. Alpha 94, three days later, is the version stamped on the published Quest Language Dictionary that remains the language's reference document
2008
Alpha 96, dated 8 June 2008, adds the string commands STRLWR and NTH_TOKEN and ships the WoS Tactics mini-game. Alpha 97 follows as the last release: the download page records it as "Updated 12/5/2008", and the installer served from synthetic-reality.us still carries a Last-Modified date of 6 December 2008

Notable Uses & Legacy

Evergreen

The world that ships with Well of Souls, written by Dan Samuel with monster and hero art by Josh Worts. The developer documentation points authors at wos/worlds/evergreen as the worked reference implementation of the language, and its quest.txt is where most world builders learned QUEST.

Monkey Town

A downloadable world by Ben Samuel - the author's son, whose ideas Synthetic Reality credits throughout its games - distributed through the game's built-in "Check On Line For New Worlds" menu.

Narretidem Islands

A third-party world by James Gregory, listed on Synthetic Reality's Other Worlds page and distributed in-game; an example of the player-authored worlds the scripting language existed to enable.

Furtopia

A player-built world by the community member Lord FireFox, who also ran one of the WoS fan sites linked from the official download page.

Aerianell

A world by Lady Gryphon, credited on Synthetic Reality's Other Worlds page as contributing their own monster artwork alongside Josh Worts' shared skins - the full stack of custom content the world format allows.

Running Today

Run examples using the official Docker image:

docker pull
Last updated: