
	       Tileworld (The X Window System Version!)
				Copyright 1990, Martha E. Pollack


			     PROGRAMMER'S GUIDE

The Tileworld system was designed and developed at SRI International,
Menlo Park, CA, by Martha E. Pollack, Michael P. Frank, and Marc
Ringuette.  This Programmer's Guide was written by Michael P. Frank.




CONTENTS (Search for these strings)
-----------------------------------
Introduction
Tileworld System (Loading and Compiling)
Modular Design of Tileworld
The "XTILE" Package, Naming Conventions, and Globals
Porting Tileworld to Other Sites
Porting Tileworld to Another Lisp (Lucid-Dependencies)
Porting to Another Window System (X-Dependencies)
Hooks

Introduction
------------

Tileworld is package, a system, a module, a directory, a set of
sources, a set of binaries, a conglomeration of functions, and an
X-windows application.  Oh, did we mention?  It's also an interactive
facility for running simulations of different agent architectures
operating in a simple environment called the Tile World.  But that's
not what's important here.  This is the Programmer's Guide.


Tileworld System Definition (Loading and Compiling)
---------------------------------------------------

The Tileworld system is organized and defined, for the purposes of
proper loading and compilation, using a special public-domain utility
for this purpose, called "DefSystem", designed by Mark Kantrowitz at
CMU.  This utility may be found in ~tile/cl-util/defsystem.lisp.
The file ~tile/tw.lisp startup file loads this file.  Next, it sets up
defsystem's *central-registry* variable to point to the ~tile/reg
directory, which tells Defsystem where to find system-definition
files.  The file ~tile/reg/xtile.system tells Defsystem how to
compile and load tileworld.  So tw.lisp loads this file, also.  It's
also possible to just (require 'xtile), and Defsystem will
automatically look for it in the central-registry directory.  Then,
all that's needed to load tileworld is to call Defsystem's
"operate-on-system" function, giving it the arguments 'xtile and
either 'compile or 'load.  tw.lisp sets up appropriate abbreviations
for this, (c) and (l).  (c) will automatically recompile only those
source files that have changed since they were last compiled.  Thus,
development is very easy, it involves making a change, saving it, and
then going to lisp and typing (c).  ~tile/reg/xtile.system takes
care of all the dependencies that are important in determining the
order of loading and/or compilation.


Modular Design of Tileworld
---------------------------

This is explained fairly well by the README files in the various
tileworld directories, but some more needs to be said.  The central
code of Tileworld is divided into fairly separate "agent" and "world"
modules.

There is another module, the "exper" module, which is a high-level
shell around the central modules, that allows playing multiple games
with different parameters, and loading and saving
experiment-definition files.

The user-interface is separated from the central code very well, and
is in completely separate files from the central code, mostly in the
"ui" module.  However, those files associated specifically with the
agent, world, or exper modules are present in those modules.

The exper module calls functions in both the agent and world modules
to run the simulation, and all three in turn call the ui module to do
the actual work of the user-interface.

Finally, there is a "basics" module that contains miscellaneous stuff
that is used by everything.


The "XTILE" Package, Naming Conventions, and Globals
----------------------------------------------------

All of the files that make up tileworld are read into the package
"XTILE" (or 'xtile), which "uses" (the technical Common Lisp term)
the xlib package (i.e., CLX, the Common Lisp X Interface) and the
lucid-common-lisp package (Common Lisp plus Lucid's extensions).

Because all the symbols in tileworld are confined to this package,
there isn't so much worry about symbol-name conflicts between
tileworld and other packages which users may have in their
environment.  However, just to make tileworld functions easier to
identify when debugging, or to find when grepping through source, many
functions in tileworld start the prefixes "tw-" or "xtw-" (depending
on whether they are in the central code or just in the new X-windows
version).  However, sometimes we developers got lazy and didn't start
our functions with these prefixes.

Throughout the newer code, all global (proclaimed special by defvar)
variables are identified with asterisks at the beginning and end of
their names.  However, in the older code, there are a number of
globals without the identifying asterisks.  The worst ones are u, d,
l, r, and n, (see world/tw.lisp) which hold the move-structures for
various directions.  PROGRAMMERS MUST BE CAREFUL NEVER TO TRY TO USE
THESE LETTERS AS LOCAL VARIABLES.  This is a programming-style bug
that needs to be fixed someday.

Almost all the globals in the newer code have an additional prefix
identifying what module they belong in.  These variables begin with
"*world-", "*agent-", or "*exper-".  Someday, the older code should
also be brought up to date to reflect this convention.

Most globals in the newer code are defined in "basics/defvar.lisp",
although some globals that are used in only a single file are just
defvar'ed at the top of those files. 


Distributing Tileworld 
-----------------------

Tileworld has been designed and developed using Lucid Common Lisp
Version 4.0, including CLX (the Common Lisp X Interface).  Details of
how to port and install the system are given in the Installation
Guide.


Porting Tileworld to Another Lisp (Lucid-Dependencies)
------------------------------------------------------

Although we haven't yet attempted to port Tileworld to another common
Lisp, we expect that the only big stumbling-block will be the
foreign-function-call interface.  The file
~tile/agent/foreigndefs.lisp will almost certainly have to be
completely replaced.  Eventually we may have different versions of
this file for different lisps.

Besides, we hope to reimplement the planner anyway, in the
not-too-distant future.  The new version may be done all in Lisp,
eliminating the need for the foreign-function interface and making the
whole system much more portable.

WARNING: There may be other Lucid-dependencies lurking in the code
that we've overlooked.  One way to find Lucid-dependencies is simply
to take lucid-common-lisp out of xtile's "use" list in
"basics/package.lisp" and see if everything still works.


Porting to Another Window System (X-Dependencies)
-------------------------------------------------

This will probably be harder than porting to another Lisp would be.
It will require major code redesign, since another window system will
have a whole different set of concepts from the one that X has.
Fortunately, the window-system-specific code is restricted to the
xtile/ui module, and to the xtile/*/*-ui.lisp files in other modules.
Someone porting to another window system should not have to change the
other files much at all.


Hooks
-----

Hooks, in the sense we're using, are function calls (or macros) that
implement important, general pieces of functionality that are intended
for easy modular replacement.  They are often points of interface
between separate program modules.

xtw-with-open-display form
	Evaluate form in the context of having the window system
	open and ready for display.  Unwind-protect to close the
	display, if needed.  All user-interface activity is done
	within this context.
	Called by: exper/exper.lisp (run)
	Defined in: ui/ui.lisp

xtw-with-ui-defaults form
	Evaluate form in the context of having dynamic variables
	bound to useful default values for our user-interface.
	Can assume the display is open.
	Called by: exper/exper.lisp (run)
	Defined in: ui/ui.lisp

xtw-with-experiment-ui form, xtw-with-world-ui form, xtw-with-agent-ui form
	Same as xtw-with-ui-defaults, but binding variables that
	are important for specific modules.  Can assume that the
	general ui defaults are bound.
	Called by: exper/exper.lisp (run)
	Defined in: modulename/modulename-ui.lisp

xtw-main-loop
	Should implement the main loop for tileworld.  Can assume
	that it's in the appropriate user-interface context
	(i.e., open-display and all).  Should not terminate until
	we're ready to quit.
	Called by: exper/exper.lisp (run)
	Defined in: exper/exper.lisp

xtw-step
	Perform a single step of the simulation.  Should never
	take more than a fraction of a second, so that in between
	steps, the user-interface can respond to input events
	without a great delay.   Can assume it's being called in
	the context of having everything set up properly.
	Called by: exper/exper.lisp (xtw-main-loop)
	Defined in: exper/exper.lisp
	Note: Calls functions in both the agent and world modules to
	actually do the work, but those functions are highly
	inter-related, so they can't really be listed as hooks.  Read
	the code to see how it's done.

xtw-start-experiment
	Assuming that the values of the appropriate global parameters
	have been set up, initialize everything, based on these parameters,
	to the start of a game of the simulation.  Can assume the
	user-interface has already adjusted itself to the parameter
	values; so it just needs to initialize internals.
	Called by: exper/exper.lisp (start-game)
		   exper/exper-dialog.lisp (xtw-reset)
	Defined in: exper/exper.lisp

xtw-world-start, xtw-agent-start
	The parts of the job of xtw-start-experiment corresponding
	to the world and agent modules.
	Called by: exper/exper.lisp (xtw-start-experiment)
	Defined in: modulename/modulename.lisp

xtw-event-loop work-form
	Given a work-form, alternate between evaluating it and
	checking for events.  When *busy* is nil, don't execute
	the work-form, and instead just block and wait for events.
	When an event is found, pass the data about it to each
	function in *handlers*.  Return when *quit* is non-nil.
	Called by: exper/exper.lisp (xtw-main-loop)
	Defined in: ui/ui.lisp

xtw-ui-reset
	Assuming the values of appropriate global parameters have
	been set up, initialize/reset/adjust the entire user-interface
	to properly reflect the new values of the parameters.
	Called by: exper/exper.lisp (start-game)
	Defined in: ui/ui.lisp

xtw-exper-ui-new-param, xtw-world-ui-new-param, xtw-agent-ui-new-param
	The parts of the work of xtw-ui-reset corresponding to the
	respective modules.
	Called by: ui/ui.lisp (xtw-ui-reset)
	Defined in: modulename/modulename-ui.lisp

xtw-world-display world
	Display the current state of the given tw (world) structure.
	Can assume that xtw-with-world-ui and xtw-world-ui-new-param
	have done their jobs, whatever that is.  Should be quick
	enough to be done many times a second. (Does 20 or so currently.)
	Called by: world/tw.lisp (tw-display)
	Defined in: world/world-ui.lisp

That's about it.  There are probably more functions internal to the
agent and world code that are sufficiently modular to be called
"hooks".  There is also modular code internal to the user-interface,
but it's not general enough to qualify.  If you're programming and you
get stuck, just remember what old Obi-Wan Kenobi said: "Use the
source, Luke."

