
		S C I    C H A N G E S   &   U P D A T E S
		******************************************
			
			in reverse chronological order
			------------------------------


2/13/89	Pablo

	Scripts now have properties script and caller, plus a setScript method.
	This allows one to give sub-scripts to a script, so that scripts can be 
	used in a fashion similar to procedures calling procedures. setScript for 
	all classes that support it now accepts an extra argument to fill the 
	caller property of the script. A script's caller is cue'd when a script 
	is disposed, imitating the behavior of completed motions and cycles. 
	Scripts should self-dispose in their final state to take advantage of 
	this capability.
	
	Also, a third argument is accepted to fill a script's register at init 
	time.
	
	A script's handleEvent passes events to its sub-script.
	
	example:
	
			(instance foo of Script
				(method (changeState newState)
					(switch (= state newState)
						(0	(Print "foo: punting to foo1...")
							(self setScript foo1 self self)	;<-- NOTE EXTRA ARGS!
						)
						(1	(Print "foo: back from foo1...")
							(self dispose)
						)
					)
				)
			)
			
			(instance foo1 of Script
				(method (changeState newState)
					(switch (= state newState)
						(0	(Printf "foo1: hi\nclient %s\ncaller %s\nreg %s" 
								(client name) (caller  name) (register name) 
							)
							(= seconds 10)
						)
						(1	(Print "foo1: bye...")
							(self dispose)					;<-- SELF-DISPOSING SCRIPT
						)
					)
				)
			)
	

2/9/89	Bob

	Sometime in the recent past, the OnControl kernel procedure was
	changed to REQUIRE a first argument of which bitmap you were
	interested in examining.  The first argument should be either
	CMAP or PMAP or VMAP.  
		The statement (= bits (OnControl x y))

	must be changed to 
		The statement (= bits (OnControl CMAP x y))
	to achieve the same results.

		The statement (= bits (OnControl PMAP x y))
	will return the bits of the priority bitmap (similarly for VMAP)


1/27/89 Bob

	The kernel procedure, AddToPic, has been redefined.  It now takes a
	list of PicViews (or sub-classes of PicView) as its sole argument.
	This change will NOT affect programs that do not explicitly re-draw
	the addToPics.  If you do need to re-draw the addToPics, use the
	following line: 
		(addToPics doit:)

	If anyone out there is using the old AddToPic kernel routine, please
	see me on possible alternate implementations.

1/26/89 Pablo

	New method for collections (and lists and sets) called "release":
	it deletes all elements from a collection in order to deallocate the list 
	nodes. Unlike dispose, it does NOT dispose the elements.
	
	Used "release" to fix fragmentation caused by use of sorted features in 
	User.


1/17/89 Bob

	Hide/Show of stop updated actors should now work much better.
	Please inform me of any problems you may still encounter.


1/5/89 Jeff

	The time at which you receive a cue: upon completion of a motion or cycle
	class has been changed.  It used to be that you would be cue:d at the
	beginning of the animation cycle following the motion completion.  Now
	you are cue:d during the animation cycle in which the motion completes,
	but after the animation is shown on the screen.

	The main game loop looks something like

		(1)	execute doit:s of cast
		(2)	update screen
		(3)	execute Game's doit:
		(4)	execute doit:s of regions
		(5)	execute User's doit:
		(6)	go to 1

	Before, if a motion were completed in (1), you would not receive the
	cue: until (1) of the NEXT animation cycle, after all the other doit:s
	were executed.  Now, the cue: comes between steps (2) and (3) of this
	loop on the SAME cycle in which the motion was completed.  This lets
	you know when the motion completes on the screen in time to set up
	to do something on the next animation cycle.


1/3/89 Pablo

	YET ANOTHER WORD VOCAB FORMAT!
	By popular demand I have changed the format accepted by the vocab 
	preprocessor to use a free-form prefix syntax like SCI itself. 
	The vocab.vc file should now consist of arbitrarily nested 
	parenthesized expressions. Each expression should start with one 
	or more preprocessor directives. A directive can be one of the 
	following:
	
	#synonyms:					all words within list have same word number.
	#number:						arbitrary jump in numbering.
	#<any part of speech>:	all words within list will carry this P.O.S.
	
	In addition, the special word ++ will increment the word number 
	without outputting a record. This should be used to avoid 
	rebuilding the entire game when a word gets deleted from the 
	middle of the word list.
	
	Example vocab.vc:
	
	(#noun #number 100
		car
		(#synonyms stone (#verb rock))	;rock is both a noun and a verb
		++
		clock
	)
	
	(#number 3000)
	(#verb
		look
		feel
	)
	
	For more complete examples, see \games\sci\system\vocabase.vc and 
	\games\ice\source\vocab.vc
	
	To compile your vocab.vc incorporating the basic system word list,
	type "vcomp vocab.vc".


12/21/88 Pablo

	Avoider offScreenOK
		new property, defaults to FALSE, if set to TRUE then 
		the avoider will allow its client to move off screen.
		
	Feature z
		new property, represents elevation of an object. This is important 
		because (+ y z) gives the y of a feature's PROJECTION on the ground.
		
		The reason we care about this is that if ego is facing south and is 
		in front of a counter, any object on the counter has a y smaller than 
		ego's, so it is computationally BEHIND him. If we take z into account, 
		then (+ y z) can be greater than ego's y, so the object can be 
		correctly considered to be IN FRONT of ego.
		
		Actor's distanceTo has been modified to take z into account.
		Default z is 0.
	

12/21/88 Pablo

	NEW WORD VOCAB FORMAT
	There is a new preprocessor for vocabulary files that allows one to 
	create a file (vocab.vc) in a friendlier format, without word numbers and 
	specifying parts of speech for entire groups of words. There is also a 
	basic vocabulary in \games\sci\system that contains words with parts of 
	speech other than adj, verb or noun, which are game-specific.
	
	New format:
	
	-	No parenthesis are used.
	
	-	Words with the same word number go on contiguous lines, blank lines
		cause the word number to increment.
		
	-	The default part of speech for all following words can be set with a 
		line like
					#SPEECH noun
		This is a vcpp (vocab preprocessor) directive, flagged by an inital #.
		If a given word following this directive is also a verb then just 
		follow the word with the additional part of speech.
		
	-	The current word number can be set with the NUMBER directive, for 
		example
					#NUMBER 1000
					
	-	Recommended procedure for all games in development:
	
		Use the new base vocab, define ONLY adjectives, verbs and nouns.
		Use s:bones.vc as a template for your new vocab, starting adjectives 
		at 500, verbs at 1000 and nouns at 2000.
		1-499 and 4000-4095 are word numbers reserved for system use.
		
	INSTRUCTIONS
	
		Create a file named vocab.vc in the new format and copy 
		\games\sci\system\vcompcfg.bat to your vocab directory. Use s:bones.vc 
		as a template and look at s:vocabase.vc for a complete example of new 
		format syntax.
		
		To help you convert your old vocab.txt files to the new format, I have 
		posted two utilities that can be invoked through the following batch 
		files:
		
			vocabare:	strips parenthesis and word numbers from each line
			vocwords:	leaves only the words on each line.
			
		If you organize A COPY of your current vocab.txt by parts of speech 
		and insert enough meaningful comments, you can then use one of these 
		utilities to do most of the conversion grunt work. The resulting file 
		should be mush easier to maintain.
		
		Type:
				vcomp vocab.vc
				
		this will invoke the preprocessor to create a partial vocab.txt, 
		concatenate it to vocabase and hand the result to good old vc.exe to 
		produce vocab.000
		
		If you have any questions I'll be glad to answer them and help out 
		with your vocab conversion.

12/12/88 Pablo

	There is a new global variable called "egoBlindSpot" which should contain 
	the size of ego's blind spot in degrees, ie. how many degrees from 
	"straight  behind" are not visible to ego. Default is zero (360 degree 
	vision), recommended value is 90 (ego only sees ahead). If 
	useSortedFeatures is TRUE then objects in ego's blind spot do not have 
	their handleEvent method invoked on Said events.

12/1/88
	(Jeff) Disk errors (no disk in drive, non-formatted disk in drive, etc.)
	are now handled better.  The user has the option to retry or quit in all
	cases but save/restore, where he has the option to retry or cancel the
	save/restore.  Let me know if you encounter any odd behavior.


11/23/88

-	(Jeff) Added the overlay: method to class Room to overlay the current
	picture with another.  Usage is

		(curRoom overlay: picNumber [showStyle])

	This restores correctly, whereas overlaying with a direct kernel call
	will not.  This supports only one overlay.  Let us know if you need more
	than one.


11/22/88

-	(Pablo) Perspective handling has changed to a hopefully cleaner paradigm.
	Instead of specifying Tilt* properties for rooms, one may now provide 
	values for vanishingX and vanishingY, the coordinates of the picture's 
	vanishing point. The default vanishing point is at 160,30000 to provide 
	the old behavior as a default. By specifying a vanishingY of say -200 one 
	can get more intuitive response to the vertical cursor keys, thus 
	avoiding ego's bumping against walls.


11/21/88

-	(Jeff) Initialized global and local variables are now a reality.  Some
	examples of syntax:

		(local
			foo1							;just as before
			[foo2 3]						;just as before
			foo3	= 1
			foo4	= [1 2 3 4 5]
			[foo5 5] = [1 2 3]
			[foo6 3] = -1
			foo7 = [{a string} {another string}]
			foo8 = 'look/rock'
		)

	which will generate the following initial values:

		foo1		0
		foo2		0
					0
					0
		foo3		1
		foo4		1
					2
					3
					4
					5
		foo5		1
					2
					3
					0
					0
		foo6		-1
					-1
					-1
		foo7		pointer to {a string}
					pointer to {another string}
		foo8		pointer to 'look/rock'

	Syntax for globals is similar, though as usual you can't declare a global
	as an array with square brackets.

	The script.xxx files generated by the new compiler will be larger than
	before because they now contain the local variables (which used to be
	allocated at run time).  However, since most variables will be the default
	of 0, compression will pretty much reduce them to the same size as before
	for your volumes.

	A WORD OF CAUTION: Whenever compiling multiple modules which include your
	room 0, you must compile your room 0 first.  All knowledge of the global
	variables other than their number is discarded after the first module, so
	
		sc rm001 rm000

	would not generate the global variables in room 0 as it should.

		sc rm000 rm001

	would, however, work.



11/19/88

-	(Pablo) New AVOIDER:
	A completely new avoider is in, rewritten from the ground up. It now 
	lives in its own file avoider.sc, separate from motion.sc
	
-	Class Motion has two new methods:
	
		setTarget:	updates the x and y properties, doing nothing else
		onTarget:	returns TRUE or FALSE
		
-	Class Room has five new properties:
	
		picAngle		0	;how far from vertical is our view? 0-89
		xTiltTop		0	;clockwise tilt from x-axis at y-0 (degrees)
		xTiltBottom	0	;same at y=SCRNHIGH
		yTiltLeft	0	;clockwise tilt from y-axis at x=0
		yTiltRight	0	;same at x=SCRNWIDE
		
	picAngle is useful to make distanceTo: behave more realistically, and 
	Orbit motions will follow an ellipse instead of a circle for non-zero 
	values
	
	The Tilt* properties completely describe the point of view used to draw a 
	room. Actor's setDirection: has been rewritten to take these values into 
	account so that hitting a cursor key will cause ego to follow the room's 
	apparent directions instead of strict screen coordinates.
	
	To figure out what values to use for these properties, use your 
	eyeball-meter and then trial-and-error to fine-tune. As far as I can 
	tell, typical values are roughly:
		
		picAngle		60
		xTiltTop		0
		xTiltBottom	0
		yTiltLeft	20
		yTiltRight	-20
		
	Finding good values for these properties will make it a lot easier for 
	people to play the game without a mouse.
	
		


11/16/88

-	(Jeff) A relatively major change in the way selectors are handled by the
	compiler and interpreter has been made and will require a change in
	syntax of your source code.  Fortunately, there is a conversion program
	which will do the syntax change for you, though you will need to learn
	a few new habits for writing new code.

	The nature of the change is that there is no longer a distinction between
	the various forms of a selector, i.e. "state:", "state?", and "state"
	are identical in all respects except visually.  The interpreter now deals
	with the message

		(anObject aSelector [args ...])

	in the following way:

		(cond
			(- aSelector is a method of anObject
					The method aSelector is invoked with args.
			)
			(- there are no arguments
					The value of the property aSelector is returned.
			)
			(- else
					The value of the property aSelector is set to the
					value of the first argument.
			)
		)

	This leads to several niceties:

		-	The selector symbol table in sc will now be only a third as large
			as it is currently, so you'll have a bit more space for your compiles.

		-	You can now convert between properties and active values with no
			source code changes outside the class involved.  An 'active value'
			is a value which has some sort of side effect when accessed.  See
			the document "/games/sci/system/doc/active.doc" for a further
			explanation.

		-	System code has been reduced in size by 300 bytes since (for esoteric
			reasons) we now have 128 more byte-length selectors.  Don't be usin'
			that space, though -- a new Avoider is on the way once Pablo gets
			well which will eat it all back up.

	What this requires in terms of syntax is the following:

		-	Multiple messages to the same object in an expression must now
			be delimited by commas, so that the compiler can tell where each
			message ends.  Thus,

				(ego
					view: 5
					posn: 100 200
					setMotion: MoveTo y x self
					init:
				)

			becomes

				(ego
					view: 5,
					posn: 100 200,
					setMotion: MoveTo y x self,
					init:
				)

		-	All 'pseudo-selectors' such as 'at:', 'title:', etc. in Print,
			SetMenu, and other function calls must be preceeded with a '#' to
			let the compiler know that you're just passing a number rather
			than trying to access a property.  Thus,

				(Print "This is a pain." at: 100 100)

			becomes

				(Print "This is a pain." #at: 100 100)

	The good news is that there is a conversion program, cvtsci.exe, which
	will do all this syntax conversion for you.  Usage is

		cvtsci file_spec [file_spec ...]

	You probably just want to 'cvtsci *.sc'.  This program can also be run
	over already converted source, so if you forget to use the new syntax
	while modifying an already converted file, just cvtsci it again.

	Note to the sceptical: the entire source of Leisure Suit Larry II has
	been converted, compiled with the new compiler, and played to completion
	on the new interpreter.  You really shouldn't encounter problems.  If
	you do, I'm sure you'll let me know.


11/14/88

-	If the set:, setReal:, and setCycles: messages are sent to an instance
	of class Timer, that instance will be used.  If they are sent to the
	Time class itself, the class will create a new: instance and set that
	instance, returning its ID:

		(instance myTimer of Timer)
		(local
			anotherTimer
		)

		(myTimer set: 10)							;uses myTimer as is
		(= anotherTimer (Timer set:10))		;creates a new: Timer

-	The stop: and dispose: methods of Sound now take an optional argument
	which tells the sound whether or not to cue: its client.  A value of
	FALSE means not to cue:.  No argument retains the current behavior,
	which is to cue: the client.

-	A fade: method has been added to class Sound.  For those with sound
	systems which have volume controls, this will fade the sound into
	oblivion, then cue: the Sound's client.  For the rest of us, it is
	equivalent to stop:.


11/11/88

-	Class User has acquired 3 new properties. They are:
		blocks: If TRUE, sounds will be stopped when User is getting input.
		x: 	Same behavior as X component of Print 'at:' command
			If set to -1 the user input window is centered horizontally
			Any other value specifies the X coord of the left edge.
		y: 	Same behavior as Y component of Print 'at:' command
			If set to -1 the user input window is centered vertically
			Any other value specifies the Y coord of the top edge.

		If your game wants to keep playing sounds while getting input
		from a window centered horizontaly at the bottom of the screen,
		send this message to User in your init:

			(User blocks:FALSE x: -1 y: 160)

		(Bob H)
					
11/03/88

-	I haven't documented the new structure of MAKEVOLS yet, so in the
	meantime, look at \games\pq2\sci\play\resource.txt and puzzle it out.
	By the by, Friday, Nov 4 is my 37th birthday so don't hassle me.


10/25/88

-	Notes on the use of &rest:
	There is a bug in &rest which is not likely to be fixed right away, but
	there is a fairly simple workaround.  The problem arises when &rest is
	used in an message send with a computed reciever, as in:

		((expression) arguments &rest)

	The above expression will be evaluated as

		((expression &rest) arguments)

	which is clearly not what is intended.  The work around is to do the
	message send in two steps using a variable to contain the computed
	reciever:

		(= reciever (expression))
		(reciever arguments &rest)


10/24/88

-	Changes have been made to both the kernel and the compiler to speed
	up critical sections of kernel code.  They should be transparent to
	game programmers except that you will now need vocab.994 (on s:) in
	order to run your game.

	NOTE TO SYSTEM PROGRAMMERS: when remaking the system from now on,
	use the -O option of sc to cause it to write vocab.994.  This contains
	the offsets to certain properties of certain classes, allowing the
	kernel to look them up much more quickly.  The classes and properties
	which are affected are in "offsets.txt", which must be kept in synch
	with the enum in "i:selector.h".


10/20/88

-	To change pictures within a room, you should use the drawPic: method
	of Room (curRoom drawPic: 100).  This method NOW disposes of any
	addToPics that have been accumulated.  This cures a symptom of
	restoring a room with the alternate picture up and seeing disembodied
	views on the screen.



10/19/88

-	The SC compiler now has a -a option which aborts the compile immediately
	if the class database is locked.

-	The debugger now has full command-line editting, using the same routines
	as those used by edit items in dialogs.  You can even use your mouse.
	Also, stepping across sends & calls (using Tab) works again.


10/17/88

-	&rest should now work with kernel functions.  Let me (Jeff) know if you
	have any more problems.

-	(Printf) now works.  Syntax is just like C's function:

		(Printf formatString [parameter parameter ...])

	Note that if you want to do anything fancy (like titles, fonts, centering,
	etc.), you'll still need to use (Print (Format @str ...)).  However, for
	simple print windows (particularly for debugging), Printf works just fine.


10/04/88

-	A class browser (a la Smalltalk) is now available as the BRIEF macro
	"browse.m" in s:.  Compile with "cm browse".  I believe that it will only
	compile for BRIEF v2.xx.  For those running v1.xx, try changing such
	things as "(+= foo bar)" to "(= foo (+ foo bar))", etc.  Or upgrade to
	v2.xx!

	To run the browser, assign a key to run the macro "BrowseClasses" or
	use the "execute macro" function to run the macro.  The browser needs
	an environment variable, "browse", which is the path along which to
	search for the source code for the classes.  You'll probably just want
	to "set browse=s:".  The browser also uses a small file, ro.com (in y:
	on the net), to determine whether or not a file is read-only.  This
	program, invoked as "ro file", returns a DOS exit code of 1 if the file
	is read-only, 0 otherwise.

	When you invoke the browser, there will be a small delay, then a menu
	of the system and user-defined classes will appear on the left of your
	screen.  This menu (generated by the new sc compiler in the file "classes")
	also shows the hierarchical relationships of the classes.  Select a class
	by using the arrow keys, Home, and End or typing in the name of the class
	you want to inspect (an incremental search is done based on what you've
	typed).  When the highlighted bar is on the class you want, press Enter.
	If you want to bail out, press Esc or Alt-minus (this applies to all
	windows in the browser).

	A new menu will be displayed which contains the selections "DOCUMENTATION",
	"PROPERTIES", and the names of any methods which the class defines or
	redefines.  Select an item as above and again press Enter.  What happens
	next depends on what you selected:

		PROPERTIES
			A new window pops up showing the properties which the class either
			defines or whose value it redefines.  This is a display-only window
			-- you can't edit in it.

		DOCUMENTATION
			Pops up a window displaying the class heading of the class, which
			is where we will be documenting the class.  This is a quick way of
			finding out what the class is about.  Any suggestions on improving
			the documentation might be welcome.  This is a full editing window,
			allowing you to scroll through and edit the source file containing
			the class.

		method name
			Pops up a window displaying the selected method.  Again, this is
			where documentation on the method will be kept and the window
			is a full editing window.

	If the source file which is found for the class is read-only (those on
	s: are), the browser will beep and display the message "File is readonly."
	to let you not to make any changes which you expect to save.

	If you make any changes in the file and then press Esc, you will be asked
	if you want to save the changes: your options are (a)bort [forget the
	changes], (w)rite [save the changes], and (c)ontinue [dont' leave the file
	yet].

	One caution: BRIEF claims to only support three pop-up windows at a time.
	When you're browsing a class you'll have that limit on the screen, so
	popping up another window (todo list, game.sh, buffer list, etc.) might
	blow you away.  Not knowing the internals of BRIEF (would that I did!),
	I can't say what will occur.


10/03/88 "Feature" class (Pablo)

-	A new class call Feature is now available. A feature is an object with 
	properties x and y and a HandleEvent method. Its purpose is to respond to 
	Said events (user input). Features must be static instances, and get 
	added to the global features list by using a new room method called 
	SetFeatures. A room's dispose method now disposes of all features, since 
	they are conceptually room-local.
	
	The x and y properties are only used if a procedure called sortedCpy in 
	user.sc is uncommented (in a private copy of course). What this does is 
	cause actors, props and features to get a shot at the said event in order 
	of decreasing proximity to ego, which is more realistic. However, 
	enabling this capability takes up a few hundred bytes of space so I have 
	left it out of the system-wide version of user.sc. See me if you want to 
	enable it.
	
	Example:
	
	Create a simple feature with:
	
	(instance Table of Feature
		(properties
			x	100
			y	120
		)
		(method (handleEvent event)
			
			(cond
				((or	(event claimed?)	(!= (event type?) saidEvent)) 
					(return)
				)
				((Said 'look/table')
					(Print "there is an empty cup on the table")
				)
			)
		) 
	)
	
	and activate it in a room's init method with:
	
	(self setFeatures: Table Chair Pot)	;this room has three features
	
	

10/03/88 TRIGONOMETRIC FUNCIONS (Pablo)

-	GetDistance now takes an optional 5th argument, perspective, which 
	is the users point of view of the room in degrees away from the vertical 
	along the y axis. The typical value for Sierra games seems to be about 60 
	degrees. This argument defaults to zero if absent. What this change does 
	is to make each y-pixel represent a greater distance than an x-pixel, a 
	behavior closer to reality.
	
	I suggest modifying the distanceTo: method to use a global variable
	called perspective that could be reset in each room init.
	
-	Four kernel calls have been added to perform integer trigonometry.
	All four take as args an angle in degrees and a number.
	
	(SinMult anAngle aNumber) returns aNumber*sine(anAngle)
	(CosMult anAngle aNumber) returns aNumber*cosine(anAngle)
	(SinDiv anAngle aNumber) returns aNumber/sine(anAngle)
	(CosDiv anAngle aNumber) returns aNumber/cosine(anAngle)
	
	CosDiv, for example, is used in the new GetDistance.
	
	All other trig operations can be built from these four calls.
	

10/03/88

-	Class Game has notify: and setScript: methods and a 'script' property
	just like Region and Room.  Thus, your room 0 can now have a script and
	communicate with Regions and Rooms.

-	The class Locale has been added (in game.sc).  A Locale is similar to
	a Region, but only has a handleEvent: method.  It is the object of choice
	for handling default responses to user input which used to go in Regions
	(e.g. 'look/meadow', 'look/tree', etc.).

-	The source code in s: is now much more heavily commented.  We'll try to
	keep the comments up to date and useful enough to replace the documentation,
	which just never seems to be current.



09/27/88

-	Resource usage tracking is now available with the '-u' option on sci.
	When resource tracking is enabled, the interpreter will write a line
	to the file "resource.use" each time a resource is loaded from disk.
	The line is of the form

		rmxxx  resType.yyy

	which indicates that resource type resType, number yyy, was loaded in
	room xxx.  Since the resource cache is flushed on each newRoom: when
	resource tracking is on, this will indicate which resources each room
	uses.

	A more useful report than "resource.use" can be generated by

		sort <resource.use | uniq >uses

	which prepares a sorted list with duplicate lines removed.

	Note that "resource.use" is APPENDED to each time you run sci with
	resource tracking on -- it is not overwritten.  You will want to delete
	it periodically to keep it from growing too large or to keep the
	usage patterns current.



09/26/88

-	The order in which various elements of your game get control has been
	changed.  It used to be that control went first to the cast, then the
	user, then the regions.  One sort of problem which was created by this
	was the following from KQ4:

		-	The cast gets control and advances ego to the edge of a cliff
			where ego is positioned on the control line at the edge.
		-	The user gets control next and types 'wear crown'.  This is
			duly parsed and passed to the handleEvent: methods, which decide
			to start ego's transformation to a frog.
		-	Control now passes to the regions, which note that ego is on a
			control line and attempt to start ego falling.
		-	Much confusion on screen.

	The modification just made now passes control first to the cast, then
	to the regions, then to the user.  This should solve problems arising
	from the scenario above.  It might, however, lead to other problems of
	a timing-related nature which we haven't anticipated.  If you suspect
	that this change has done you in somehow, please talk to one of us --
	we may be able to come up with a way around your problem, or the change
	can be backed out (it only involves swapping two lines of code).


09/25/88

-	The 'o' and 'O' commands in the debugger now display all objects in
	one window in which the new: objects are preceeded with a '*'.  This
	gives you a better feel for where objects are positioned in relation
	to each other.

-	Many changes have been made to the Sound class.  The 'keep' property no
	longer exists -- to stop a sound from playing without disposing it,
	just invoke the stop: method:

		(mySound stop:)

	The dispose: method still exists, and not only stops the sound but
	disposes its soundNode (an internal kernel structure) and the sound
	itself if it is a new: object.

	The play: method of Sound now sets the 'loop' property to 1 if it is
	0 when play: is invoked.  Thus, the expression

		(mySound loop:1 play:)

	may now be written

		(mySound play:)

	if you can be sure that the loop property is either 0 or 1.

	Sounds now have an 'owner' property, which can either be left empty (= 0)
	or set to the ID of a Region or Room.  When a Region or Room is disposed,
	the system disposes all sounds with either no owner or which are owned
	by the Region or Room being disposed.
	
	Sounds are no longer automatically disposed when they finish, only on
	room/region changes.  Because of this, a sound which might be played many
	times in a room (e.g. a non-fatal fall or playing an instrument) should
	be an instance rather than a new: Sound.  Since the new: sound will only
	be disposed on a room change or if you explicitly dispose: it, (Sound new:)
	can potentially fill the free heap.

	To minimize heap fragmentation of sounds in regions, make them instances
	of Sound, initialize them in the init: of the Region, and set their
	owner to the region, e.g.

		(mySound owner:thisRegion init:)

	Do not dispose: sounds in regions -- only stop: them.  Since dispose:
	frees several sound structures in the heap, the next time the sound
	is played it will reallocate them ABOVE the current room, leading to
	fragmentation when you leave the room.

	The general rules of thumb for sounds are:

		-	Always make sounds instances of Sound -- don't use (Sound new:).
		-	Never explicitly dispose: a Sound unless you're sure you know
			what you're doing -- use stop: to turn it off.  Sounds will be
			automatically disposed on Room/Region changes using their 'owner'
			property.


09/21/88

-	Sci accepts a '-d' command line option to enable debugging.  This
	means that you will get a 'PMachine' error rather than an 'Oops!',
	and be dropped into the debugger as before.  As time marches on,
	more of the debugging facilities will be added to this switch.


09/18/88

-	The debugger is now invoked by pressing the "grey minus" (numeric pad)
	while both shift keys are down.  Also, PMachine errors are reported
	in a shippable manner UNLESS you have invoked debug via the keyboard
	prior to encountering the error.  This is subject to change, stay tuned
	for developments.

	NOTE: On the TANDY 1000, the proper minus key is the one also marked
	DELETE.  You must have numlock OFF to access it.

09/16/88

-	Prioritized sounds are now a reality.  The 'priority' property of Sound
	is a signed integer which defaults to 0.  If you tell a sound to play:
	and a lower priority sound is already playing, the new sound will interrupt
	it, play to completion, and then restart the old sound at the point of
	interruption.  If the new sound has a priority equal to or lower than the
	old sound, it will wait for completion of the old sound before it plays.

	There are three properties of interest for coordinating sounds with each
	other or with animation.

		signal
			This gets set to the value of an animation cue for one animation
			cycle, after which it is reset.
		prevSignal
			This gets the value of signal when signal gets set, but retains it
			until the next sound cue.
		state
			This is the state of the sound, and is one of the following:
				SND_NOTREADY
					The sound has not been initialized.  Default for Sounds.
				SND_READY
					The sound has been initialized, but not submitted for playing.
				SND_BLOCKED
					The sound has been submitted for playing, but either the
					sound is paused or a higher priority sound is presently
					playing.  (Note that since the debugger pauses sounds, an
					active sound will always appear as blocked in the debugger.)
				SND_ACTIVE
					The sound is currently playing.

	The changeState: method allows changing the priority or loop count of a
	sound which has been initialized (or is playing).  Just set the appropriate
	properties of the sound, then do a (mySound changeState:).

	You can use priorities to chain sounds together without the 'next sound'
	stuff (which will probably be eliminated soon).  Just submit the sounds
	with decreasing priorities:

		(firstSound loop:1 priority:2 play:)
		(secondSound loop:2 priority:1 play:)
		(thirdSound loop:1 priority:0 play:)

	Will play one loop of 'firstSound', two loops of 'secondSound', and one
	loop of 'thirdSound' in that order.

	To terminate a sound at the end of its loop rather than immediately, just
	set its 'loop' property to 1 and do a changeState:

		(mySound loop:1 changeState:)

	There are times when you will want to play a sound only if no higher
	priority sound is playing (like the 'got item' music in KQ4).  Submitting
	it at a lower priority will keep it from playing when a higher priority
	sound is present, but will play the sound when that higher priority
	sound is finished.  What we want is to either play the sound immediately
	or not at all.  To do this, use the 'playMaybe:' method:

		(mySound playMaybe:)



09/14/88
-	The EndGame class and the end method of Game are kaput.
	Following is an example of how to end your game.  This example
	uses a "dead" global var to detect the need for ending.

	; this may or may not already be in your rm000
	(method (doit)
		(if dead
			(repeat
				(switch
					(Print
						"\"Thank	you for playing\n
						King's Quest IV,\n
						`The Perils of Rosella.'\n\n
						Next time... be more careful!\""
						icon: 100 0 0
						mode: teJustCenter
						title: {Roberta says:}
						button: {Restore} 1
						button: {Restart} 2
						button: {____Quit____} 3
		 			)
					(1
						(theGame restore:)
					)
					(2
						(theGame restart:)
					)
					(3
						(= quit TRUE)
						(break)
					)
				)
			)
		else
		; your normal code
			...
			...
			...
			...

			; this must be here
			(super doit:)
		) ; end of NOT dead
	)	; end of DOIT:



09/07/88

NOTE: 
	The two following changes were not arbitrary, and I will be
	willing to justify them to anyone who cares.

-	The selectors to the (Display) kernel procedure have changed.
	The following selectors are valid:
		p_at:
		p_mode:
		p_color:
		p_back:
		p_style:
		p_font:
		p_width:
		p_save:
		p_restore:

	NOTE: The colon must be included.

-	The selectors to the (SetMenu/GetMenu) kernel procedures have changed.
	The following selectors are valid:
		p_said:
		p_text:
		p_key:
		p_state:
		p_value:

	NOTE: The colon must be included.
		

-	Added code to MenuBar to respect "state" property.  If "state is
	FALSE, then handleEvent returns FALSE.


09/06/88

-	Added a new property to User.  "inputLineAddr" is the address of
	the input line being used by User to get input (sort of circular logic).
	One possible use is as follows:

	(Print 
		(Format 
			"%s, %s...\nBoy! listen to that echo!"
			(User inputLineAddr?) (User inputLineAddr?)
		)
	)



09/05/88

-	In order to get the sound state to display properly in your menus after
	a restore game, you'll need to make several changes to your code (we'd
	do it for you in the system, but the system doesn't know the details of
	your menus).

	1) Break the enum for your menu items out into a "menu.sh" file.  This
		has the added advantage of letting you include the file in any module
		in which you wish to do something to your MenuBar.

	2)	Include "menu.sh" in the file which includes your instance of Game
		(rm000, kq4, or whatever).

	3)	Redefine your Game's 'replay' method as

			(method (replay)
				(SetMenu soundI
					text:
						(if (DoSound SoundOn)
							{Turn sound off}
						else
							{Turn sound on}
						)
				)
				(super replay:)
			)

	'Replay' is the method which is invoked by the system instead of 'play'
	when a game is restored.  If you need to do any setup on a restore (versus
	a restart, which invokes 'play'), put it in this method.  The
	(super replay:) must ALWAYS come at the end of 'replay', since it contains
	the main game loop.

-	Ego should be able to leave a room under diagonal motion now.  In order
	to do this, class Ego now ignores the horizon.  Let me know if this
	causes any problems.



09/02/88

-	The initialization of the menu bar hase been removed from the
	(theGame init:) method.  Each game must now init it at the proper
	time.  You can achieve the behavior that you're accustomed to by
	adding the following line to your room 0 right after the call to
	super init: in your game init:

		(TheMenuBar init:)

	If you wish to defer the drawing of the menubar, you should remove
	the line (self draw:) from your menu init and place the following line
	where you want the menubar to first become visible:
		(TheMenuBar draw:)

	NOTE: an undraw menubar will still respond to user input. ie.. ESC
		clicks, key strokes and typed input.

-	MoveTo has been fixed to not skip over control lines.  The fix
	reduces the effective speed of motion of Actors that fit this
	general set:

		xStep <> yStep - The greater the difference, the greater the affect
		heading NEAR nw, ne, sw, or se.

	This may cause some skating in actors with vastly different step sizes.
	Please see Bob H. for more details.

-	Sound volume is now in.  See the volumeI item of s:menu.sc for how
	to implement it.

-	Sound volume and sound on/off state should be retained across
	restore/restart.  This change requires some change to your menu handling
	of sound.  Look at the sound stuff in s:menu.sc to see how to modify it.

	You can find out what the current sound state is by doing a
		(DoSound SoundOn)
	Do not use the old 'value' feature of the sound menu to track the state --
	querying the interpreter directly is much safer.

	Volume (0-15) can be queried by
		(DoSound SoundVolume)





08/30/88

-	ShakeScreen is now supported.  The kernel call is as follows:
	(ShakeScreen n [d])
		n = 	number of shakes, 1 to 64K
		d = 	direction to shake; 1 = down, 2 = right, 3 = down/right
			default direction is down
			
-	Save/restore dialogs have been modified.  Should handle full-disk
	conditions, disk changes, etc. much better.



08/30/88

-	There is a global variable named 'version' which should now point to
	the version string for your game.  In the init: of your game, put the
	line

		(= version {x.yyy.zzz})

	if you're using incver.exe to maintain your game version number (you
	should be).

	This will allow more stringent checking for validity of games before
	restoring them.



08/29/88

-	There is a new basic Sierra menu (menu.sc) on the net.  It contains
	the code for echoing the input line (using modifications to User outlined
	below) and for setting animation speed and sound volume (using class
	Gauge outlined below).
	It also contains modifications to the said specs for various items.  A lot
	of caution must be exercised in writing menu said specs, since the MenuBar
	gets the first shot at events.  For example, using 'save' as the said spec
	for saving a game means that if the user types 'save man' he will get the
	save-game dialog.  The said spec should be 'save[/game]'.

-	Class User has a new property, 'prompt', and a new method 'getInput'.

		prompt
			This is the text which will be displayed above the edit box when
			the user starts typing.  Its default is 'Enter input', but it can
			now be changed (e.g. to 'Give her your best line, Larry').

		getInput:char
			Collects a line of input from the user and passes it on to the
			parser.  The first character of the input line is 'char' unless
			'char' is (User echo?), in which case the previous input line
			is echoed.  The default value of 'echo' is now the spacebar.
			The use of F3 for echoing is done through the menu, which invokes
			(User getInput:(User echo?)).

-	A new class, Gauge, has been added to the system.  A Gauge is a dialog
	which uses a thermometer-like gauge to allow the user to adjust something
	(animation speed, sound volume, etc.)  A kindof Dialog, it has the
	following added properties and methods:

		description
			This is the text which appears above the thermometer and tells
			the user what is being adjusted and how to adjust it.  E.g.
					"Use the mouse or right and left arrow keys to
					select the speed at which characters move."

		higher
			This is the text which goes in the button which increases the
			value of whatever is being adjusted.  Its default is "up".

		lower
			This is the text which goes in the button which decreases the
			value of whatever is being adjusted.  Its default is "down".
			
		minimum
			The minimum allowed value of whatever is being set.  Defaults
			to 0.

		maximum
			The maximum allowed value of whatever is being set.  Defaults
			to 15.

		normal
			This is the value of whatever is being adjusted which you, the
			game programmer, consider the normal value.  Defaults to 7.

		update:
			A method used internally.

	As for Dialogs, the 'text' property is the title of the Gauge.  To use
	the gauge, do

		(= newValue (Gauge doit:currentValue))

	where 'currentValue' is the current value of whatever you want adjusted.
	The doit: method of Gauge returns the value selected by the user.

	Gauges for animation speed and sound volume are now built into the
	standard menu.

	A Gauge needs about 1K of heap to run, and can be disposed immediately
	after use: (DisposeScript GAUGE).  The class should be included on all
	volumes.

-	The inventory dialog now supports up- and down- arrows as well as Tab
	and Shift-Tab.




08/23/88

-	save: and restore: methods of Game now prompt for disk changes if
	the current device is the target and is removable.  In support of
	this, the following kernel calls have been added:

-	(StrAt string position [char])
		StrAt returns the character at 'position' in 'string'.  If the optional
		'char' is specified, it replaces the character with 'char', returning
		the old contents.  Use this rather than the mask-and-shift method
		which I expounded to Teresa (sorry...), since byte order in a word
		will vary between machines.

-	(DeviceInfo function @string [@string])
		DeviceInfo returns information about file system devices.
		The functions are:

			(DeviceInfo GetDevice @path @device)
				Puts the string describing the device component of 'path'
				into the string pointed to by 'device'.  Thus, if
				path = "g:/games/kq4/sci", device = "g:".  If there is no
				device component in 'path', puts the current device in 'device'.

			(DeviceInfo CurDevice @device)
				Puts the string describing the current device in 'device'.

			(DeviceInfo SameDevice @dev1 @dev2)
				Returns TRUE if the strings pointed to by 'dev1' and 'dev2' are
				the same physical device, FALSE otherwise.

			(DeviceInfo DevRemovable @device)
				Returns TRUE if 'device' is removable, FALSE otherwise.



08/22/88

-	Class Extra (see 8/19/88) is now officially part of the system.  Like
	Jump, etc., it takes no overhead unless you use it.



08/19/88

-	New stuff has been added to allow semi-automatic adjustment of animation
	to the speed of a machine.  Here's how it works:
	
	A global variable called 'aniThreshold' contains the animation interval
	(see 'aniInterval' below) which you consider to be just barely acceptable
	(the default system value is 10).  After the startRoom: method of the
	Game has been invoked in the process of doing a newRoom:, the checkAni:
	method is called.
	
	checkAni: does animation cycles (only drawing objects, not calling their
	doit: method) and checks aniInterval against aniThreshold.  If aniInterval
	is too large, checkAni: looks for the first member of the cast which is
	marked as an 'extra object' and does an addToPic: on it.  It continues to
	do so until either aniInterval drops below aniThreshold or it runs out of
	'extra objects' in the cast.

	To mark an object as 'extra' (not to be confused with the class Extra in
	development by Al Lowe et. al.), use the isExtra: method:

		isExtra: TRUE			;marks the object as an extra
		isExtra: FALSE			;unmarks it
		isExtra:					;returns the current status

	Things such as sparkles or ripples on water, woodpeckers in trees, etc.
	could all be dropped out in this manner.  Note, though that if an object
	is added to the picture in this manner, it will no longer be accessible
	through any object ID you had before.  The class Extra (below) is, by
	default, marked as extra.

-	A new class, Extra, developed by Al Lowe is in s:extra.sc.  It will be
	made a part of the system on Monday (which will require a recompile of
	the world).  An Extra is a subclass of Prop which waits for a random
	time interval, then cycles for a random interval and repeats.  It's great
	for people reading magazines in waiting rooms, woodpeckers pecking trees,
	etc.  It has the following extra properties:

		pauseCel
			Cel to pause on when not cycling: -1 for random cel, -2 for last cel
		minPause
			Minimum number of animation cycles of no action when paused.
		maxPause
			Maximum number of animation cycles of no action when paused.
		minCycles
			Minimum number of animation cycles of cycling when active.
		maxCycles
			Maximum number of animation cycles of cycling when active.

	This class is, by default, an 'extra' in the sense used above in regard
	to animation speed, and so will be added to pic if the machine is too
	slow.

-	'O' and 'o' work in the debugger again -- the stack size reduction had
	killed them.  In fixing that, I also added code to keep inventory items
	from being displayed, so the static object display won't be so cluttered.

-	The old global variable named 'overRun' has been renamed to 'aniInterval'
	(animation interval) and now contains the number of timer ticks that it
	took to do the most recent animation cycle, rather than how much longer
	than 'speed' it took.  This is a much more useful value.

-	Icons are now centered in a Print window if there is no accompanying text.

-	Edit window length now more closely matches the number of characters
	which can be typed.  Also, the input line and save-game description
	have been lengthened.

-	The parser recognizes modifiers once again.



08/15/88

-	Several new PMachine opcodes have been introduced, leading to more
	space efficient code.  The system object code size was reduced by
	about 1200 bytes.



08/12/88

-	Menu stuff, which doesn't seem to have been written up before:

	You can modify an existing menu with the 'SetMenu' kernel command, which
	has the following syntax:

		(SetMenu itemName selector value [selector value ...])

	where itemName is the name by which you refer to your menu item and the
	the available selectors are

		said: newSaidSpec			change the said spec for the menu item
		text: newText				change the text displayed in the menu
		key: newKey					change the key which selects the menu item
		state: newState			= dActive to enable menu item
										= 0		 to disable menu item
		value: newValue			change the value to return when selected

	For example, you can disable the save-game menu item (which we'll assume
	is refered to by 'saveI') with

		(SetMenu saveI state:0)

	The 'GetMenu' kernel function returns the current values of a menu item
	corresponding to the selectors listed above.  Thus,

		(GetMenu soundI text:)

	would return a pointer to the text corresponding to the soundI menu item.


08/11/88
-	Install no longer passes the colon ":" to instgame.bat.

-	New debugger command: 'S' shows the size and maximum and current stack
	usage of both the processor ('Proc') and PMachine ('PMach') stacks.

-	New constants for show styles
	;Picture change style constants
	(define	HWIPE			0)
	(define	HSHUTTER		0)
	(define	VSHUTTER		1)
	(define	WIPELEFT		2)
	(define	WIPERIGHT	3)
	(define	WIPEUP		4)
	(define	WIPEDOWN		5)
	(define	IRISIN		6)
	(define	IRISOUT		7)
	(define	DISSOLVE		8)
	(define	BLACKOUT		9)

	adding the "BLACKOUT" constant to any of the styles
	will blacken the screen in the converse manner before showing
	picture.
		(curRoom drawPic: PIC23 (+ IRISOUT BLACKOUT))
	
			
08/10/88

-	Save/Restore game and sounds should now work much better together.
	Let me know if there are any restore game problems from now on (1 PM).


08/09/88 

-	PARSER, VC.EXE: Word derivation rules are now kept in a text file
	called DERIV.TXT, with a syntax similar to that of VOCAB.TXT. The 
	vocabulary compiler has been modified so that it will compile both of 
	these files when invoked. Comments are allowed in .TXT files following
	SCI syntax, ie. starting with a semicolon ";". 
	
	A rule to handle plurals might be:
	
	(*men noun *man noun) ; ie. firemen/noun -> fireman/noun
	
	Multiple parts of speech can be specified for each pattern.There is a
	sample DERIV.TXT in the system directory. 
	
	For the parser to function correctly, you must now have VOCAB files
	.000 (dictionary), .900(grammar) and .901(derivations)  present at 
	runtime.[Pablo]


8/08/88

-	The restore: method of Game now takes an optional parameter.  If this
	parameter is TRUE, the restore game dialog will be displayed only if
	there are saved games in the current save-game directory.  This allows
	you to put up a restore dialog at the beginning of the game, which is
	a great convenience to the user.  Just put the following in the init:
	method of your game:

		(if (not (GameIsRestoring))
			(theGame restore:TRUE)
		)

-	The setCursor: and setSpeed: methods of Game now return the old values
	of the properties which they are replacing.

-	New debug features!
		-	Variables displayed in the debugger are now editable.
		-	Breakpoint is back in an object-oriented reincarnation.  Pressing
			'b' in the debugger prompts for an object name (or ID), then for
			a method name.  Once those are entered, execution begins and
			continues until execution enters the indicated method of the object,
			at which point the debugger is invoked.  If no method name is
			entered (i.e. if you press Esc at the 'in method' prompt), a
			breakpoint is invoked whenever the indicated object becomes
			current.


8/05/88

-	When adding a button to a Print, you MUST supply a value to return
	when that button is selected.  This WILL make it possible for a
	TRUE/FALSE test instead of a switch.
	(if 	
		(Print 	"May I have a K of code please?" 
			button: {Be my guest} 1
			button: {Kiss my node pool!} 0
		)
		; take a K of code and smile
	else
		; sulk and be moody
	)
	[Note that through no fault of either the compiler or the Print code,
	the above test will always test false.]

-	Display default width is NOW, the required width of the message
	with NO word wrap.  To enable word wrap, you must pass a WIDTH:
	argument that is greater than or equal to 0.  If you pass 0, the
	width will be determined in the same ratio as the (Print) procedure.

-	StatusLine should now be redisplayed on restart: and restore:.

-	(GameIsRestarting) now returns RESTARTING/RESTORING if you're in the first
	animation cycle after a restart:/restore:.

-	The wordFail: method of Game now gets two parameters: the word which
	was not recognized and the user input line.

		(method (wordFail word input)
			...


8/04/88

-	Added command line switch (-r) to sciv.  When used, will
	Alert user when a new volume is opened on the same physical
	media.  Has no bearing on the file based version.



8/03/88

-	Redefined "buttons" and their handling in Print procedure.  
	You may add up to 5 buttons to a print message.  They are 
	added to the window, aligned horizontally, from left to right
	in the order that you specified them.  If one of them is selected,
	Print returns the number of the button (1 through n) to you.  You must
	take action accordingly as below:
	(switch (Print "Please click on button A." 
				button: {A} button: {B} button: {C})
		(0
			(Print "You pressed ESC")
		)
		(1		
			(Print "Very good!")
		)
		(else
			(Print "Wrong button")
		)
	)

	PLEASE NOTE: This change saved 142 bytes of memory.

-	Refined modeless dialogs (Print dispose:).  A "dispose:" print
	sets the global, modelessDialog to point to it.  This variable,
	if not zero, WILL point to a dialog that can be disposed of via
	(modelessDialog dispose:)  A timed dialog will also ensure that
	this global is zeroed when the timer times out.  If a game is 
	SAVEd, RESTOREd or RESTARTEd, SOMEBODY must dispose of this window
	or it will hang around forever OR in the case of save, not be valid
	when the game is restored.
			

8/2/88

-	New save game interface, with more error checking.

-	New kernel procedure (CoordPri yCoord).  Returns the priority
	that corresponds to yCoord. 
		; make body the same priority as the feet in a split actor
		(body setPri: (CoordPri (feet y?)))

-	Additional command line editing keys:
		CTRL-C clears entire line
		HOME   moves to beginning of line
		END    moves to end of line


