Syntax

Introduction

This page discusses what the original syntax of the SCI language may have looked like.

Clues

There are not very many clues available regarding the original syntax of the SCI language. Those that are available are discussed below.

The Official Book of King's Quest

This is a book written by Donald B. Trivette, in which there are a couple of clues related to the original syntax of the SCI language:

Description of the Language

On page 16 (chapter 2) of the first edition, it has this to say about the Script Interpreter:

"The programmer is the one who puts all the rooms and animated characters together to make the game run. He does this using a special computer language called SCI (SCript Interpreter) developed by Sierra. SCI is an object-oriented language similar to LISP; it's written in Assembler, C, and itself."

Note: Although this book contains sample code snippets, these are unfortunately from the older AGI language and not SCI.

What does this the above description tell us? 
  • SCI is an object-oriented language.
  • SCI is similar to LISP. So mostly likely what this means is that it is wrapped in lots of parentheses and it uses the infix notation.

SCI Classes

On page 17 the book mentions the Actor class, the View class and the Prop class. On page 18 it mentions Wander, Chase and MoveTo.

Ex-Sierra Employee Comments

These are few and far between. However there are a couple:

Mark Wilden's Smalltalk Page

At the time of writing, you can find this page at the following address: http://web.archive.org/web/20101219175024/http://www.mwilden.com/smalltalk/index.htm. Mark has this to say about the SCI langauge:

"SCI was a combination of Lisp, C and Smalltalk, but the message-passing was very much Smalltalkesque. I loved the language."

And strangely he has this to say about LISP:

"So what did the Unix haters like? Well, Lisp. I'm sorry, but I cannot get into Lisp (I tried hard during my six-month Linux-Java-Emacs phase)."

And on his blog he says this about SCI:

"They had actually created their own language, SCI, that was a very pure implementation of OOP. I'll never forget that first night reading the documentation on my bed and just being consumed with this language that did things I wanted to do and even things I didn't know I wanted it to do.

Ever since then, I've run into lots of people who talked about the difficulties of making the paradigm shift to OOP. But not me. It was love at first sight."

Here is another comment from Mark, this time from a Smalltalk forum:

"Sierra On-Line used a proprietary language for their adventure games which had many similarities to Smalltalk. There weren't blocks, but you could override methods in instances."

What does this tell us?
  • In addition to LISP, SCI is apparently similar to Smalltalk.
  • The message passing in particular was very similar to Smalltalk. Note that Smalltalk message passing syntax is a well known message passing style and is also used by Objective-C.
  • Very curiously though, Mark could not get into LISP and yet he loved SCI. This suggests that although SCI may have been LISP-like, it quite clearly wasn't LISP; or at least it wasn't LISP-like enough to remind Mark enough of what he disliked about LISP.

J. Mark Hood Interview 

An interview with J. Mark Hood (http://www.gamasutra.com/view/feature/4130/from_sierra_to_korea_j_mark_.php?page=3)  has the following to say:

"I was doing language design, and they happened to be doing a new language to create computer games with -- adventure games -- called SCI. And they were developing this new object-oriented development language, and there were very few people actually back then that were doing object-oriented [programming]...

Well, it turned out that SCI was very good at making games really fast, and so I started becoming just in charge of running the object-oriented toolset and building up the class library."

What does this tell us?
  • Once again it stresses the object-oriented nature and that fact that it was a very new concept at the time.
  • It tells us about the existence of a class library, which ties in with what The Official Book of King's Quest says regarding parts of the language being written in itself. Clearly what this means is that there was a standard set of classes written in the SCI language that all SCI games had access to. This compares with what languages like Java have, a standard set of classes that comes with the language and that you can always expect to be available.

Standard SCI0 Debug Mode

Everyone knows about the standard debug mode that all SCI0 games had built in. It was activated with SHIFT-SHIFT-MINUS (the minus on the keypad). So what exactly can the debug mode tell us about the syntax of the original language? If you type in "s" when in the debug mode, it shows you something called the Send Stack. If you then step through the SCI instructions using the debugger, you will see the send stack get more and more items added to it, for example:

(sounds eachElementDo:)
(Game doit:)
(KQ4 doit:)
(KQ4 play:)

What does this tell us?
  • The use of parentheses suggests that what this is showing us is the LISP-like syntax of the language.
  • The Send Stack is clearing showing us a method invocation on an object, or "message sending". For example, the eachElementDo: message is being sent to the sounds object. This is why it is called a Send Stack.
  • Ignoring the LISP-like use of parentheses, the messaging passing syntax shown in the Send Stack is very suggestive of Smalltalk syntax, which ties in with what was claimed earlier on Mark Wilden's web site about the SCI message passing being very Smalltalkesque.

Selector Names

As mentioned elsewhere on this site, the file VOCAB.997 contains the selector names for the game. If you skip ahead and read the section below entitled "Smalltalk Message Passing" then you'll get an idea of what a selector is. The reason that this file is interesting in relation to the original SCI syntax is because it helps us to see similarities to other programming languages. All classes in the SCI programming language extend from the Object class. This class is in contained in the file SCRIPT.999 along with all the other non-adventure classes, such as Collection, Set, List, Code, Script and Event. The Object class is very interesting as regards the investigation into the original SCI language syntax. These are a few of the method names on that class (you can see these in VOCAB.997 and track them back to the Obj class in SCRIPT.999, or for the easier approach you can load up VOCAB.997 in SCI Companion to see these):

isKindOf
isMemberOf
respondsTo
yourself
perform

If we type this into Google and hit search, the results are mostly for Smalltalk, Squeak or Objective-C. Squeak is a Smalltalk implementation. Objective-C is a language that adds Smalltalk-style messaging to the C programming language. There is a common theme here. If you examine the results a bit closer, you'll notice that the results that actually have the unbroken strings above in them are almost all Smalltalk results. Here are a couple of examples:


What does this tell us?
  • An effort was made by the designers of the SCI class system to make the root Object look very similar to the Smalltalk Object class, which strongly supports the claim that the original syntax was influenced by Smalltalk.
  • This further confirms the earlier claim that parts of the language were written in itself, i.e. if the Object class is written in the SCI language (which it is) and the methods defined in that class are from Smalltalk, then part of the nature of the language is itself defined by SCI code.

PMachine Instruction Set Clues

SCI programs execute on a virtual CPU or what is known as a PMachine (which stands for p-code machine or pseudo code machine). A PMachine has a pseudo machine language, which is a set of machine instructions for a machine that doesn't really exist. It exists solely in software. The most common examples of this these days are the Java virtual machine and the .NET virtual machine but the idea has been around for a long time, since around 1966.

Here are a few links to information about the SCI PMachine (these actually are all to the same page of the SCI specifications but I've added all three just in case one or more of these links change over time):


The instruction set of the SCI PMachine can tell us a few things about the original SCI syntax.

Arithmetic Operators

The SCI PMachine instruction set contains a full set of arithmetic instructions. Each of these instructions will map 1-to-1 with an arithmetic operator in the SCI language. For example:

add maps to (+ arg1 arg2)
sub maps to (- arg1 arg2)
mul maps to (* arg1 arg2)
div maps to (/ arg1 arg2)

Relational Operators

There is likewise a 1-to-1 mapping between the relational instructions in the instruction set and the equivalent operators in the SCI language. For example:

eq? maps to (== arg1 arg2)
ne? maps to (!= arg1 arg2)
gt? maps to (> arg1 arg2)
ge? maps to (>= arg1 arg2)

A more detailed analysis of the arithmetic (and logical and relational and bitwise) operators will be covered in the Operators page.

Send Instruction

Where things get interesting is with the send instruction. Let's reproduce the description of this instruction from the SCI specifications:

"Send looks up the supplied selector(s) in the object pointed to by the accumulator. If the selector is a variable selector, it is read (to the accumulator) if it was sent for with zero parameters. If a parameter was supplied, this selector is set to that parameter. Method selectors are called with the specified parameters.

The selector(s) and parameters are retreived from the stack frame. Send first looks up the selector ID at the bottom of the frame, then retreives the number of parameters, and, eventually, the parameters themselves. This algorithm is iterated until all of the stack frame has been "used up". Example:

; This is an example for usage of the SCI send operation
  pushi x      ; push the selector ID of x
  push1        ; 1 parameter: x is supposed to be set
  pushi 42     ; That's the value x will get set to
  pushi moveTo ; In this example, moveTo is a method selector.
  push2        ; It will get called with two parameters-
  push         ; The accumulator...
  lofss 17     ; ...and PC-relative address 17.
  pushi foo    ; Let's assume that foo is another variable selector.
  push0        ; This will read foo and return the value in acc.
  send 12      ; This operation does three quite different things.

Something that immediately strikes me about this is that it is sending multiple messages using what is effectively keyword syntax. The example above is essentially a keyword message (see the Smalltalk Message Passing section below for a description of this). There is a single "send" instruction being invoked but there are three different messages. This is something that doesn't happen in VMs such as the Java VM. In the Java VM the stack frame contains data for invoking a single method. The Java invoke VM instructions invoke a single method and there are separate instructions for changing and getting fields (AKA properties). In SCI, however, we can see that all of these things can be done with "send". This says something about the higher level language and what it can do. It suggests keyword messages as used by Smalltalk.

Fan-made SCI IDEs

There are two fan-made SCI IDEs at the time of writing. These are SCI Studio and SCI Companion. The fan-made IDEs have embraced the idea of the original syntax being LISP-like. The authors of these tools had very few clues to go on when they implemented the language syntax. It has been known since 1988 when The Official Book of King's Quest came out that the syntax was LISP-like. So this has been embraced by the IDEs. It wasn't known until fairly recently that SCI syntax was also strongly influenced by Smalltalk. For this reason the syntax used in the IDEs has no similarity to Smalltalk. Instead it uses a C like syntax for invoking procedures and methods. The reason I have listed the fan-made IDEs as a "clue" is not because of the syntax that they use but because of the keywords that they use (note that in LISP these are referred to as "special forms" and not keywords - see LISP section below).

The template game source code that comes with these IDEs was reverse engineered from the original games data files. It therefore gives us a clue about the "types" of keyword/statement that the original SCI language must have supported but perhaps not necessarily the actual names of those keywords. If we look through the source code of the template game, we can see the following keywords: if, for, while, switch. It is highly likely that the original language supported structures of these types. The reason for this is that when the template game source was reverse engineered, it would have been fairly obvious to the person doing that manual decompilation from the patterns of byte code within the compiled scripts that these language structures must have existed in the original language. For example, repeated testing of a single variable against multiple values suggests a "switch". If the testing of a variable's value is only against a single value then it suggests an "if". If, however, the testing of a variable's value is within a loop where a branching instruction jumps back above the test then perhaps it is the condition test for a "for" loop or a "while" loop. Recognising the difference between these would be a matter of what it does at the top and bottom of those loops. 

What does this tell us?
  • The existence of "if", "for", "while" and "switch" keywords in the fan-made IDEs suggests that the original SCI language had similar keywords.

Smalltalk Message Passing

More than one clue above has suggested a Smalltalk syntax to the SCI message passing. This has been confirmed by ex-Sierra employees. So let's do a bit of research about what Smalltalk message passing is like. In "An Introduction to Object Oriented Programming" by Timothy Budd, he has this to say about Smalltalk's message passing:

"Smalltalk and Objective-C use a slightly different syntax. In these languages a space is used as a separator. Unary messages (messages that take no argument) are simply written following the receiver. Messages that take arguments are written using keyword notation. The message selector is split into parts, one part before each argument. A colon follows each part of the key."


Here is another description of the Smalltalk messaging passing style in this article entitled "Simplicity Makes the Difference that Makes the Difference" by Peter William Lount:

"Smalltalk's language syntax is in part based upon "keyword" and "parameter" pairs delimited by a colon character, ":", for "setting" or "passing" a paramter to an object one writes the keyword as "x: 100" or "name: 'tom'" for keywords with single parameters, and "x: 100 y: 699" for multiple keywords and multiple parameters. When "getting" a parameter value from an object one simply uses a keyword without the parameter (and colon)."


And this six page PDF has a nice visual explanation of the Smalltalk message passing syntax on page 3: 


The Smalltalk message passing syntax is sometimes referred to as "keyword notation" or "keyword syntax" but appears to be more commonly called "keyword message". 

What it all boils down to is this, using the standard terminology, is this:

receiver selector: argument

where the receiver is an object. If we wrap this in LISP-like parentheses we get this:

(receiver selector: argument)

And for multiple messages we get this:

(receiver selector1: argument selector2: argument1 argument2)

The following example shows how this would be used in a SCI game:

(ego x: 100 y: 150)


LISP-like Syntax

One thing that has been known about the original SCI syntax for a long time is its LISP-like syntax.

Characteristics of LISP

So what is it that makes something LISP-like? What are the characteristics of LISP that make it recognisable as LISP?

"Lisp uses the distinct S-expressions or prefix notation. This notation can be summarized as (function arguments...). You always start with the name of a function, and list zero or more arguments to pass in to that function. The function and its arguments are organized together by surrounding them with parentheses. This leads to one of the trademarks of Lisp: a lot of parentheses."


"S-expressions are probably best known for their use in the Lisp family of programming languages. They are typically represented in text by parenthesized, whitespace-separated sequences of character strings, as in (= 4 (+ 2 2)), which represents the Boolean expression commonly written as 4==2+2 in C and its related programming languages.

In Lisp, the first element of every S-expression is an operator and any remaining elements are treated as data. This is called "prefix notation" or "Cambridge Polish notation"."


"Polish notation, also known as prefix notation, is a form of notation for logic, arithmetic, and algebra. Its distinguishing feature is that it places operators to the left of their operands."


The above quotes are all telling us essentially the same thing. It all boils down to this:

(function arguments...)

which is equivalent to this:

(function [argument1 argument2 ...])

A function might be an arithmetic operator, e.g.:

(+ 3 5 6)

...or a relational operator:

(> y 5)

...or a logical operator "special form":

(and (< x 5) (> y 6))

...or perhaps a flow control "special form":

(if (< x 4) ...)

...or even a user defined function. Everything follows the same general pattern. The last two examples, however, are not standard LISP expressions. They are what LISP calls "special forms". They are primitives defined by the language that are necessary for things such as flow control. In other languages we might call them keywords but in LISP "keyword" has a very different meaning so I'll attempt to avoid using that term from now on. "Special Forms" are expressions that appear to look like standard LISP expressions but that do not follow the normal rules of evaluation. For a normal expression in LISP, all arguments are evaluated in the order from left to right. For example:

(+ (- 5 3) (* 2 2) (+ 2 4))

It makes sense to us just by looking at the above expression that all of the arguments to + will get evaluated and the end result will be 12. In the case of a "special form", this does not happen. For example:

(if (< x 4) (print "Hello"))

Clearly we don't want the second argument to be evaluated if x is greater than or equal to 4. The "if" special form has semantics that says only evaluate the second parameter if the first parameter equates to true. This type of behaviour does not conform to the normal rules of evaluation in LISP. For some more information of LISP special forms, see the following:



The following page is a quite interesting comparison of the most common LISP dialects. It gives us a feel for the types of operation that is common to LISP.


Note that Scheme is the oldest of the four common dialects. Scheme and Common LISP are the most common these days but Common LISP was fairly new when the SCI language was invented, so Scheme would probably have had the most influence if any.

How LISP-like was it?

In the last section we explored some of the characteristics of LISP, the things that make it visually recognisable as LISP. But since SCI was supposedly a combination of LISP, C, and Smalltalk, exactly how LISP-like was it? Which parts of the SCI language were LISP-like, which were Smalltalk-like and which were C-like? I think it is very interesting that Mark Wilden says on his Smalltalk web page that "I'm sorry, but I cannot get into LISP". This is a comment from someone who tried hard to give LISP a chance but in the end he just couldn't like LISP. On the other hand Mark describes SCI as a language that he fell in love with at first sight and that one of the highlights of his programming career was reading the SCI documentation for the first time.

So how can SCI be LISP-like and yet not remind Mark Wilden strongly enough of what he dislikes about LISP? I think we have to conclude that SCI is not a LISP. It might look like LISP visually but perhaps that is where it stops. I think in order to be LISP-like, it must have had at least these features:
  • Parenthesized, white space separated sequences of character strings.
  • Prefix notation, e.g. (+ 1 3), or more generally (function [argument1 argument2 ...])
  • Arguments are evaluated in order from left to right.
  • Some set of non-standard "special forms or operators" must exist that do not follow the standard argument execution rules, for such things a flow control.
  • Every parenthesized sequence or expression returns a value regardless of what type it is.
And that is perhaps where the likeness stops.

Putting It All Together

As was mentioned above, the syntax used by SCI Studio and SCI Companion was in part based on a small snippet of SCI code that was floating around the SCI community in the late 90s. This code snippet was short and perhaps only showed a small part of the syntax. For this reason some parts of the SCI Studio syntax are bang on the mark and others parts are very different. Ex-Sierra employees having seen the syntax used by SCI Studio have confirmed that it is definitely not the original SCI syntax. The message passing is one area that is very different.

In this section we will show a code snippet from the SCI Studio template game and then apply all of the various clues that we have discussed above to the code snippet to reach something that is closer to the original SCI syntax.

 SCI Studio Syntax Modified Using Clues Discussed Above
 
(method (delete) 
    (if(& signal $8000)
        (if(& signal $20)
            (send gAddToPics:add(
                (send (PV:new()):
                        view(view)
                        loop(loop)
                        cel(cel)
                        x(x)
                        y(y)
                        z(z)
                        priority(priority)
                        signal(signal)
                        yourself()
                    )
                )
            )
        )
        = signal (& signal $7FFF)
        (send gCast:delete(self))
        (if(underBits)
            UnLoad(rsMEMORY underBits)
            = underBits NULL
        )
        (super:dispose())
    )
)

 
(method (delete) 
    (if (& signal $8000)
        (if (& signal $20)
            (gAddToPics add:   
                ((PV new:)
                    view: view
                    loop: loop
                    cel: cel
                    x: x
                    y: y
                    z: z
                    priority: priority
                    signal: signal
                    yourself:
                )
            )
        )
        (= signal (& signal $7FFF))
        (gCast delete: self)
        (if underBits
            (UnLoad rsMEMORY underBits)
            (= underBits NULL)
        )
        (super dispose:)
    )
)

In-Game Code Generation

Quest for Glory II

Feature Writer

QFG2 has a debug command called Feature Writer. This is accessed within QFG2 by firstly typing "suck blue frog" to activate the debug mode, and then typing "ALT-W". It then takes the user through a sequence of dialogs that allows the user to define one of a Feature, a Prop, a PicView, a View or an Actor. After entering all the details, it will then display the SCI source code to the screen and also write the code into a file on the disk drive. For example, the following SCI source code was generated by QFG2 using the Feature Writer:

(instance Harry of Actor
    (properties
        x 187 
        y 136 
        z -17 
        heading 0 
        noun 'harry' 
        view 0
        loop 0
        cel 0
        description "Harry" 
        sightAngle 90 
        closeRangeDist 50 
        longRangeDist 100 
        shiftClick verbLook 
        contClick verbGet 
    )
)

What does this tell us?
  • It tells us what five of the SCI classes were called in the original SCI source code. These are Prop, PicView, Feature, View and Actor. What is interesting is that the class names that are included within the compiled scripts have Act and PV in the cases of Actor and PicView. This tells us that SCI classes could specify a shorter name for use in the binary form. Perhaps this was to save a few bytes here and there.
  • It shows us how objects were defined (in the above example, Harry is an instance of the Actor class).
  • It gives us an example of the LISP-like use of parentheses.

Write Cast To File

There is another debug option to Write Cast to a file. This produces a file with code like the following, for each Actor in the room:


(instance gate of Actor
  (properties
  view  290
  loop  0
  cel         0
  palette  1
  x  134
  y  132
  priority  7
  signal  (| fixPriOn ignrAct notUpd)
  )
)


What does this tell us?


Polygon Editor





;** Path points for picture #100

(local
  pts1 = [21 157 89 158 93 165 91 174 80 177 61 179 41 179 18 171]
  pts2 = [92 137 95 123 161 116 169 129 149 142 100 142]
  pts3 = [131 132 181 154 208 129 167 99 94 103 46 128 104 152 134 159]
  pts4 = [159 161 198 150 203 137 177 130]
  pts5 = [145 152 114 155 85 150 92 137 128 142]
  pts6 = [218 134 131 132 129 104 199 131)

;** The following belongs in the room's init:

  (poly1 points: @pts1, size: 8)
  (poly2 points: @pts2, size: 6)
  (poly3 points: @pts3, size: 8)
  (poly4 points: @pts4, size: 4)
  (poly5 points: @pts5, size: 5)
  (self
  addObstacle:
  poly1 poly2 poly3 poly4 poly5 
  )

;** Necessary objects:

(instance poly1 of Polygon
  (properties
  type: PBarredAccess
  )
)
(instance poly2 of Polygon
  (properties
  type: PBarredAccess
  )
)
(instance poly3 of Polygon
  (properties
  type: PTotalAccess
  )
)
(instance poly4 of Polygon
  (properties
  type: PBarredAccess
  )
)
(instance poly5 of Polygon
  (properties
  type: PNearestAccess
  )
)


What does this tell us?


Path Maker



;** Path points for picture #100

(local
  ePData = [2 0 0  0
                 (| PATHSTART SLICK ACTIVE 162) 146 ;** path#0
                    208 137
                    194 159
                    146 163
                    111 153
                    145 (| PATHEND 147)

                 (| PATHSTART SLICK ACTIVE 172) 154 ;** path#1
                    184 133
                    189 149
                    201 157
                    199 (| PATHEND 129)

                 0
             ]
)


What does this tell us?



SQ5, LSL6, Freddy Pharkas and Similar Later Games

Feature Writer

Some of these later games have a Feature Writer tool within the game, similar to what was discussed above for QFG2, but in addition to generating a "properties" section for the instance, it also generates the shell of a method within the instance, e.g. as follows:


(instance Bob of Actor
  (properties
  x  273
  y  169
  z  56
  heading  0
  view  220
  loop  0
  cel  0
  sightAngle  40
  approachX  273
  approachY  113
  approachDist  0
  _approachVerbs  $0
  noun  Bob
  )
   (method (doVerb theVerb)
  (switch theVerb
            (LOOK

            )
            (DO

            )
  (else
  (super doVerb: theVerb)
  )
  )
  )
)


And others like this:


(instance monitor of Feature
  (properties
  x  295
  y  27
  sightAngle  40
  noun
  )
  (method (init)
  (self setPolygon:
  ((Polygon new:)
  type:    PTotalAccess,
  init:    274 45 301 55 314 52 316 46 315 7 297 0 293 0 274 12,
  yourself:
  )
  )
  (super init: &rest)
  )
);monitor



What does this tell us?

  • It tells us that the original SCI language had a switch statement.
  • It tells us that the switch statement had a default case called "else".
  • It tells us that the switch statement did not use a "case" keyword for the other values (Note that LOOK and DO are numeric constants)
  • It shows us examples of how methods were defined, and the way that parameters were specified.
  • It shows the use of both "super" and "self".
  • It shows us that commas were used between individual messages (which is strange and not would you'd expect in the Smalltalk keyword message syntax).
  • It shows how &rest was used to pass the rest of a method's parameters as values in a message.

Polygon Editor

These later games also often have a Polygon Editor. The following are some examples of the output that this editor can produce:


; Polygon Editor 1.11
; Dynamic Obstacles : Picture 230
(curRoom addObstacle:
  ((Polygon new:)
  type:  PBarredAccess,
  init:  0 0 319 0 319 124 281 124 281 110 205 110 168 113 151 74
  147 74 147 114 134 114 129 105 51 105 51 78 37 78 37 105
  0 105,
  yourself:
  )
  ((Polygon new:)
  type:  PBarredAccess,
  init:  0 174 319 174 319 189 0 189,
  yourself:
  )
)

(altPolyList add:
  ((Polygon new:)
  type:  PBarredAccess,
  init:  135 99 135 87 163 87 163 99,
  yourself:
  )
  ((Polygon new:)
  type:  PBarredAccess,
  init: 28 103 28 100 57 100 57 103,
  yourself:
  )
)

What does this tell us?

  • It shows us an example of how messages were sent to objects (rather than to self and super as we'd already seen in the Feature Writer output)
  • It seems likely from this that curRoom was the official name of global variable 2 (which is called gRoom in the SCI Companion template game).

Dialog Editor

The third of the in-game source code generation tools is the Dialog Editor. The following is an example generated by Freddy Pharkas:


(Print
  posn:  217 113,
  addTitle:  {Testing 123},
  font:  0,
  addButton:  0 {button test} 3 3,
  addText:  {text} 3 3,
  addText:  {text} 3 3,
  addIcon:  0 0 0 3 3,
  addEdit:  @str 5 3 3 {},
  font:  2108,
  width:  20, 
  addText:  {text} 0 0,
  init:
)



Genuine SCI Code from Police Quest SWAT

The following is the genuine SCI source code that was in general circulation before the turn of the century. I had originally thought that this had been lost a long time ago. It appeared on some SCI related web sites from 1999 but most of the SCI related web sites from back then no longer exist. However, thanks to the Wayback Machine and Wikipedia, it has been found again.


If we glance over the syntax, it appears to validate most of the conclusions made above about what the syntax must have looked like.


(instance hitNineShot of Script

   (method (changestate newstate)

      (switchto (= state newState)
         (
            (theGame handsOff
            (qualProd dispose:,delete:)
            (messager say: ALL ALL QUAL-HIT-9-C ALL self 320)
         )

         (
            (++ nineShotCntr)
            (qualList dispose:)
            (target1 dispose:)
            (messager say: ALL ALL QUAL-RELOAD-9-C ALL self 320)
         )

         (
            (if (== nineShotCntr 9)             
               (Bset fQualifiedSniper)
               (curroom newroom: ANGELES-TABLES)
            else
               (targetl
                  view:    3329,
                  setloop: 2,              ;One inch target
                  setcel:  0,
                  posn:    495 370,
                  setPri:  470,
                  init: ((snipeplane casts?) at: 0)ftrlnitializer,
               )
               (= qualList (List new:))
               (qualProd setReal: qualprod 6)
               (theGame hands0n:)
               (self dispose:)
            )
         )
      )
   )

) ;hitNineShot


There are several inconsistencies and mistakes in this code, but it is repeated above in its original form. It is thought that the errors in the code might provide clues as to the original of the code. Was it typed in by hand, perhaps out of a book or magazine? The missing : and ) at the end of "(theGame handsOff" is suggestive of this, as is the inconsistent "newstate" vs "newState", and the "qualProd" vs "qualprod". It is also clear from other clues (such as the selector names in the games themselves) that the method name should be "changeState" and that "newroom" should be "newRoom". The "curroom" should likewise be "curRoom", since we've seen from in-game code generation tools that this should be curRoom. And there's a couple of others like that as well. All in all, it seems quite clear that this was not simply a copy and paste from working game source code. It has all the marks of an inaccurate copying process, be it by human hand, or perhaps by OCR.

What does it tell us though?
  • It shows us an example of a keyword called "switchto" (which is different from the earlier example of "switch" that was generated by in-game code generation tools).
  • It shows us an example of the "if" and "else" keywords.
  • It shows us a number of operators, including ==, ++ and =.
  • It shows us an example of a procedure call, being the "Bset" call.





Comments