ScriptX and the World Wide Web: “Link Globally, Interact Locally” (1995)

Don Hopkins
18 min readApr 30, 2021

by Don Hopkins, Kaleida Labs, 1995

Note: This all seems pretty obvious now, but I wrote it in 1995, before the appearance of Java and JavaScript. Of course the links don’t work any more (except to the arpanet map), and unfortunately kaleida.com didn’t get snapshot by archive.org, but this is some of the content we published on the web in 1995 that I saved. See 1995 Apple World Wide Developers Conference Kaleida Labs ScriptX DreamScape Demo for a whirlwind demo!

ScriptX Source Code:

ScriptX DreamScape Demo:

1995 Apple World Wide Developers Conference Kaleida Labs ScriptX DreamScape Demo

Benefit of ScriptX to Web Browsers

The World Wide Web is an excellent way to distribute cross-platform interactive multimedia ScriptX objects. The Kaleida Media Player, running on net-surfing Mac and Windows platforms, can dynamically load in and plug together objects from “title containers” transferred over the web.

ScriptX title containers are portable files containing ScriptX objects, code and media: text, images, animation, sound, MIDI, music, movies, and modular object-oriented programs that plug together dynamically to orchestrate open-ended interactive multimedia experiences.

You can publish self-contained multimedia ScriptX titles (i.e. applications, tools, games, catalogs, presentations, documents), as well as reusable ScriptX objects (i.e. modular components, accessories, characters, places, clip-art, plug-ins, SimProducts), so people can download the ones they want, and compose and interact with them locally, on their own computers.

Web browsers such as NetScape can be configured to use the Kaleida Media Player (KMP) as a “helper application”, so it’s simple for people with NetScape and the Kaleida Media Player to download and interact with ScriptX objects: just click on a link to a title container, and it’s distributed over the network and dynamically loaded into the Kaleida Media Player, where it comes to life!

ScriptX Pizza Demo

The ScriptX Pizza Demo, at “http://www.kaleida.com/official/pizza", lets you construct a pizza by plugging together ScriptX objects from several title containers delivered via the World Wide Web. First you select a pizza crust in one title container, then you can select any number of pizza toppings in separate title containers. They’re dynamically loaded into the KMP and locally composed in a window, that you can interact with by dragging the toppings around on the crust. There’s even a “big brother” spinning eyeball topping, that animates as you move your cursor around the screen!

This demonstrates network distribution of cross platform code and media, with local interactivity, direct manipulation, animation, dynamic binding, and plugging together objects from different containers.

There is an extension to ScriptX on the Mac that enables it to ask NetScape to open any URL, so ScriptX can cause NetScape to display a web page, load another title container, and even send messages to interactive web services (like submitting an order for a pizza).

ScriptX Web developers will go far beyond mere pizza toppings, publishing innovative interactive experiences on the network, no longer limited to the static text, graphics, and forms of HTML.

Benefits of ScriptX to Web Developers

As a general purpose object-oriented multimedia scripting language, ScriptX has many uses for web developers. It can import and export various file formats, index, search and manipulate multimedia databases, automatically generate HTML from macros and templates, draw and composite images and produce corresponding image maps, and serve as an open ended programmable hypermedia synthesizer.

For example, the ARPANet Map, at “https://donhopkins.com/arpanet/index-large.html", is a web of html, gif images, and image maps, all synthesized off-line by ScriptX from an abstract topological graph of the network.

Future Directions

As described above, there are many interesting things that can be done by distributing files generated off-line by ScriptX, including title containers, HTML pages, images, and image maps. This can be taken much further by using ScriptX as an interactive on-line web server, synthesizing distributed hypermedia on demand!

There is an experimental extension to ScriptX on the Mac that enables it to be used with MacHTTP as a “Common Gateway Interface” server. It’s possible to link to a running ScriptX program, that dynamically interprets URLs and forms results, and generates responses on the fly.

ScriptX can produce and respond to web pages with forms and pictures (buttons, scrolling lists, text fields, and clickable images), that most web browsers support. We have developed an experimental framework of classes for generating HTML from ScriptX objects, and programming interactive Web services with forms, macros, and high level HTML widgets with clickable images. It’s possible to implement image maps that send events directly back to the ScriptX presentation and model objects that rendered them. Example web services that have been implemented with this framework include class and generic browsers, and a scrolling zooming image browser.

Conclusion

ScriptX deeply satisfies an important unfilled niche in the World Wide Web: it makes it possible to implement and distribute high quality cross platform interactivity, far beyond the static HTML forms and text formatting capabilities of current Web browsers. In the long term, ScriptX is the ideal framework for developing open-ended, extensible Web servers and browsers, distributed hypermedia authoring tools, multi-user collaborative online services, and compelling online store fronts, games, and educational experiences unlike anything that’s been done before!

ScriptX Web Module Documentation

By Don Hopkins, Kaleida Labs, 1995

Introduction

This is the documentation for the ScriptX Web module. The Web module is a toolkit for integrating ScriptX with World Wide Web browsers, generating HTML, and implementing interactive services and distributed multimedia authoring tools.

Source Code:
https://donhopkins.com/home/archive/scriptx/webserve/

There are several components of the web module, that work together:

Classes for automatically generating HTML.

  • Lego-like WebElement building blocks, for representing hypertext markup structures as ScriptX objects, that know how to print themselves as HTML.
  • Nested structures are represented by WebGroup objects, that inherit from Array, and can contain strings and other recursively nested elements. WebGroup subclasses represent HTML structures like WebPage, WebHeading, WebLink, WebBulletedList, and WebParagraph.
  • Dynamic WebMacro, expands into other elements by calling your function. Defered evaluation, parameterized by key/value pairs of submitted form. Very powerful!
  • Easy to write new elements and subclass existing ones to make very interesting high level HTML widgets, like WebXeroxMapImage for embeding images of the Earth remotely generated at Xerox PARC, WebSelectProp, for selecting between one of several property values in an interactive dialog, or WebObjectAccessor, for getting and setting the value of a ScriptX variable via a Web form. The last is especially neat, since it allows you to embed any number of accessors in a form all pointing to the same externalized target, and the form submission is handled automatically by the Generic dialog. Totally automatic and stateless!
  • Gif exporter, supporting invisibleColor transparency and interlacing. ScriptX presentations can be dynamically rendered and exported as GIF images, which can be woven together with image maps or interactive services that map user input back to the actual objects in the picture.
    Image map generation utilities, for writing out image maps of arbitrarily shaped ScriptX objects.

Web Browser Remote Control Interface.

This is an interface to SpyGlass’s cross platform remote control API, that is now supported by NetScape, on both the Mac via AppleEvents, and Windows via DDE. It allows ScriptX to interoperate with Web Browsers in many interesting and useful ways.

  • “OpenURL” request from ScriptX to Web Browser, so ScriptX can tell Web Browser to follow links. Useful for bringing up remote web pages, downloading remote ScriptX title containers, as well as locally displaying dynamically generated html and gif files.
  • Automatic “Helper Application” registration. ScriptX can automatically register as a helper application for “.sxt” title container files, so it’s not necessary for the user to configure the browser manually, in order to use ScriptX as a helper application. So whenever the browser opens a URL of mime type “application/scriptx-title”, it will load the title container into ScriptX automatically. Either the user can click on a link to a title container, or ScriptX can send the “OpenURL” request to the browser with the URL of a title container, to download and run it automatically.
  • “EchoURL” notification from Web Browser to ScriptX, so ScriptX can watch the source and destination of every link the browser follows. Useful for maintaining hot lists, drawing maps, and in combination with “OpenURL” for managing navigation history.
  • Protocol registration, so when the browser opens a URL beginning with “scriptx:”, an “OpenURL” notification is sent from the browser to ScriptX, which can respond interactively by dynamically generating html and/or gif. This is the key to implementing local interactive web services with ScriptX, using NetScape as an external browser for ScriptX, and implementing tightly integrated Web authoring tools with ScriptX!

Web Server, Service, and Dialog classes, for managing OpenURL notifications, responding to service requests, and handling interactive dialogs.

This is a step on the direction of a high level cross platform native toolkit interface, as well as a non-intrusive distributed authoring tool framework. Decouple the native toolkit from ScriptX by using an external Web Browser via the remote control interface, which will only get richer and more powerful as OLE and Open Doc support is implemented. This radically cross platform approach to a native toolkit interface will also leverage the creation of Web authoring tools in ScriptX.

  • The WebServer manages lists of named WebService and WebDialog objects.
  • A WebService represents a URL you can open by name, such as “scriptx:help”. It’s defined by a function that returns a string of HTML, usually by telling a WebPage or WebMacro to print as HTML. Services are like home pages or entry points for dialogs.
  • A WebDialog represents an ongoing conversation with state, encoded in the URL as key/value pairs, like “scriptx:dialog=ClassBrowser&class=Collection”. It’s defined by a function parameterized by a KeyedLinkedList, the key value pairs, parsed courtesy of the WebServer.
  • All of the HTML printing functions are parameterized by “props”, a KeyedLinkedList of properties, that they pass recursively. So nested macros and HTML widgets have access to the properties that the WebDialog was invoked with, and can parameterize themselves off of those properties.
  • An object reference may be externalized to a magic cookie, that can be embeded in a WebPage, that’s later sent back to ScriptX as a link or a form property, and can then be internalized to return the original object. This mechanism, in conjunction with hidden form fields used to store invisible state information, can be used to encode the state of an ongoing dialog in the web page itself, including references to arbitrary ScriptX objects, so the WebDialog objects in ScriptX can be stateless templates, to support multiple independent views, etc. (Believe me, it’s a good thing.)
  • Includes a bunch of example services, like a class browser, object browser, file system browser, arpanet browser, scrolling image browser, scriptx command input, window snapshot service, etc.
  • To make it possible for normal people to write web pages without knowing HTML, there is a parser for a simple syntax called “Norml”, Network ORiented Markup Language, that lets you write paragraphs, links, headings, and outlines in a very simple format, as well as embed arbitrary html commands without restrictions. The Norml parser translates Norml text into nested WebElement objects described above, that may be programmatically manipulated and composed into higher level HTML structures, and printed out as HTML. There is a service called “scriptx:norml” that has a text input form for type Norml text, and a button that compiles it and displays it as formatted HTML.
  • The DreamScape demo includes a dynamically loaded part that provides services to inspect rooms, parts, and their images, with image maps you can click on to inspect the illustrated objects.

Building the Web module

  • Load “!mkweb.sx” into ScriptX.

DreamScape Documentation

By Don Hopkins, Kaleida Labs, 1995

Introduction

This is the documentation for DreamScape, an open ended interactive multimedia simulation environment for ScriptX, also known an Actualized Fantasy Screen Waster (not to be confused with a Virtual Reality Screen Saver). The DreamScape Demo given at the Apple World Wide Developer Conference flies through its many features.

Source code:
https://donhopkins.com/home/archive/scriptx/dream/

DreamScape consists of rooms that can connect together in a map, and parts that can move around inside and between rooms. You can load new rooms and parts dynamically, and they can interact with you and each other in interesting, unexpected ways.

The parts have simulated physical dynamic behavior. You can pick them up, move them around, and throw them, and they bounce around the room, effected by gravity and friction, colliding and interacting with each other.

Parts can be animated, and articulated with registration points, so you can plug them together like legos or Mr. Potato Head. Some can even paint on the room background, and do all kinds of other magic stuff.

There is an overall map showing every room, with icons of the current image of each room, and lines between linked rooms, that rubber-band when you drag the icons around. You can go to any room by clicking on its icon, and even edit the map topology, making and breaking connections between rooms, simply by bumping their icons together.

You can create new rooms and parts, by copying the directory of a similar one, and editing its image, director file, or startup action source code in the directory. The room images are imported from BMP files, and the Director Toolkit is used to import articulated animations from Director files. The room and part definitions are compiled into AccessoryContainers that you can dynamically load into ScriptX, as many times as you want to create any number of objects.

This first release of the DreamScape is a snapshot of a working prototype, developed as a demonstration of ScriptX by Kaleida Labs. The DreamScape Design Philosophy describes some of the concepts around which DreamScape was designed. This code is intended to serve as an example of ScriptX programming and object oriented design techniques, with the caveat that it is under development, subject to drastic change, and has its share of limitations and skanky kludges. This other documentation describes the DreamScape design example in more detail.

Building DreamScape

Load “!mktrack.sx” into ScriptX, to compile the ScriptX Tracking Service.

It depends on the file:
tracking.sx — source code

It creates the file:
tracking.sxl — Tracking module LibraryContainer

Load “!mkthrow.sx” into ScriptX, to compile the Throwing module into a LibraryContainer.

It depends on the files:
anim.sxl — Animation module LibraryContainer
tracking.sxl — Tracking module LibraryContainer
import.sx — source code
throwing.sx — source code
room.sx — source code
puppet.sx — source code
ground.sx — source code
painter.sx — source code
narnia.sx — source code
bounce.aif — audio media

It creates the file:
throw.sxl — Throwing module LibraryContainer

Load “!mkrooms.sx” into ScriptX, to compile the rooms into AccessoryContainers.

It depends on the files and directories:
anim.sxl — Animation module LibraryContainer
tracking.sxl — Tracking module LibraryContainer
throwing.sxl — Throwing module LibraryContainer
rooms/roomName — directories

It creates the files:
rooms/roomName.sxa — room AccessoryContainers
Load “!mkparts.sx” into ScriptX, to compile the parts into AccessoryContainers.

It depends on the files and directories:
anim.sxl — Animation module LibraryContainer
tracking.sxl — Tracking module LibraryContainer
throwing.sxl — Throwing module LibraryContainer
pupimp.sx — source code
parts/partName — directories

It creates the files:
parts/partName.sxa — part AccessoryContainers
Load “!mkdream.sx” into ScriptX, to compile the DreamScape TitleContainer.

It depends on the files:
anim.sxl — Animation module LibraryContainer
tracking.sxl — Tracking module LibraryContainer
throwing.sxl — Throwing module LibraryContainer
dream.sx — source code

It creates the file:
dream.sxt — TitleContainer
After it finishes saving, it runs DreamScape so you can test it out.

Running DreamScape

To run DreamScape, load the TitleContainer “dream.sxt” into the Kaleida Media Player or ScriptX. It depends on the files and directories:
anim.sxl — Animation module LibraryContainer
tracking.sxl — Tracking module LibraryContainer
throwing.sxl — Throwing module LibraryContainer
dream.sxl — DreamScape TitleContainer
rooms/roomName.sxa — room AccessoryContainers
parts/partName.sxa — part AccessoryContainers

Playing DreamScape

Here are some of the most important features of the DreamScape user interface, that you have to know to play with it. It’s fun to figure it out without reading a manual, but you may want know the following techniques. A more in-depth description of the user interface will be written later, but for now, you can refer to the DreamScape Design Philosophy for more tips.

Importing Parts and Rooms

Select “Open Accessory…” from the File menu, or type Command-Y on a Mac, or Control-Y on Windows. Select an AccessoryContainer file ending with “.sxa” from the “parts” or “rooms” directories. Importing a part adds it to the current room. Importing a room adds it to the map, but doesn’t connect it to any other rooms.

Navigating from Room to Room

To move to an adjacent room, press the mouse button down over the background, move up, down, left, or right, and release the button, without pausing. This “flicking” room navigation gesture will quickly move you from room to room. You can undo any navigation gesture by flicking back in the other direction, since all links between rooms are supposed to be two-way.

Blowing the Wind

You can blow the wind in any direction (actually warping gravity), to fly the moving parts around the room and off the edges, by pressing the mouse button down over the background, moving it in the direction and magnitude you want the wind to blow, and holding the button down. If you release the button quickly instead of holding it down, it will be interpreted as a navigation gesture, and you will move to an adjacent room. Once a part stops moving, it isn’t effected by wind or gravity any more, so you’ll have to pick it up and throw it to get it moving again.

Hitting the Brakes

You can hit the brakes (actually increasing friction), to slow down all the moving parts in the room, by pressing the mouse button down and holding it down without moving. If you move instead of holding still, it will be interpreted as a wind blowing or room navigation gesture.

Moving Parts from Room to Room

To move a part to an adjacent room, just pick it up and throw it off the edge towards that room. Use the map editor to connect and disconnect rooms.

Map Editor

The map editor floats in a window above the current room, so it is always with you no matter where you are. You can drag it almost off the edge of the screen so it is out of your way, or anywhere else on the screen you want. It has an icon for each room, which shows what each room currently looks like, at 10% scale. There are thick blue lines between rooms that are linked. You can drag the rooms around, and the lines will follow. You can make a link between two rooms, by dragging one over to the other, and dropping it down so the edges you want to link bump together. The rooms will snap apart neatly, and there will be a blue line connecting the two edges that touched. To break the link, drag the two rooms together again just like you did to link them, and the link will be broken. If you load the “parts/map.sxa” map accessory more than once, you don’t get a new map, but it performs another automatic layout of the current map. The automatic layout algorithm does OK with geographically consistent grid-like maps, but gets hopelessly confused with maps of weird topologies, so it tries to respect how you’ve moved things around. A subject for further research.

Authoring Rooms for DreamScape

DreamScape loads rooms from the AccessoryContainers in the “rooms” directory, from the “rooms/roomName.sxa” files. The rooms are defined by the files in the “rooms/roomName” subdirectories.

You can make a new room by copying one of the other room directories in “rooms”, and giving the new directory the name of your room.

Each room directory has a subdirectory called “rooms/roomName/image”, which contains a 640x480 BMP file, that’s used as the background image of the room. Edit the image to your liking, and save it into the “image” directory as an 8 bit BMP file, compressed or not, preferably using the Mac system colormap. There should only be one file in the “image” directory, and it should end with the “.bmp” extension.

You can link a room to other rooms in four directions: up, down, left, and right. You should be sure to make a link back from the other room in the opposite direction, since navigation in DreamScape is supposed to be undoable: if you move one direction, you can always get back to the same place by moving the opposite direction.

Each room directory may have subdirectories called “left”, “right”, “up”, and “down”, that each contain a single subdirectory whose name is the room adjacent to that edge. For example, to make a link between a room on the left called “foo” and a room on the right called “bar”, create a directory called “rooms/foo/right/bar”, and “rooms/bar/left/foo”. Similarly for up and down.

The map overview lets you edit links between rooms, and automatically keeps the two way links consistent. Soon it will update the room directory, so the changes are persistent (but doesn’t yet, in this first version of the prototype).

You can put parts into a room by making a subdirectory of the room directory called “rooms/roomName/parts”, and making subdirectories in there whose names are part names, defined in the “parts” directory. For example, to put a butterfly (defined in “parts/buttrfly”) into the room called “field”, make a directory named “rooms/field/parts/buttrfly”.

You can build all the rooms at once by loading “!mkrooms.sx” into ScriptX, or build a single room at a time by loading the file “rooms/roomName/!mkroom.sx” from the room directory.

Authoring Parts for DreamScape

As you might expect, DreamScape loads parts from the AccessoryContainers in the “parts” directory, from the “parts/partName.sxa” files. The parts are defined by the files in the “parts/partName” subdirectories.

You can make a new part by copying one of the other part directories in “parts”, and giving the new directory the name of your part.

Each part directory has a file named “parts/partName/startup.sx”, which contains a ScriptX function of one argument, an AccessoryContainer, that’s used as the AccessoryContainer’s startupAction, which is called and passed the AccessoryContainer when it’s loaded.

The look and feel of the part is defined by the startupAction, which may plug in various kinds of media, that are stored in the AccessoryContainer. There are several template “startup.sx” files that you can copy, and substitute your own media, without programming. If you want to program in ScriptX, you can certainly write your own “startup.sx” files to make parts that do anything you want! Try to write them to be reusable, so you can plug in new media without modifying the code.

If there is a subdirectory called “parts/partName/director”, it should contain a single Director file, that ScriptX imports as a set of named puppet parts. The parts are stored in the AccessoryContainer, for use by the startupAction to create the part. The startupAction, whose single argument is “ac”, can refer to “ac[@parts]” to get the array of imported puppet parts. Refer to the comments in “pupimp.sx” and “puppet.sx” for more information about puppet parts, and look at the director files in the examples to see how to format named animation sequences with named registration points for importing into ScriptX.

You can build all the parts at once by loading “!mkparts.sx” into ScriptX, or build a single part at a time by loading the file “parts/partName/!mkpart.sx” from the part directory.

! ! N O W ! ! G O ! ! H A V E ! ! F U N ! !

DreamScape Design Philosophy

By Don Hopkins, Kaleida Labs, 1995

DreamScape is an open ended interactive multimedia simulation environment for ScriptX, also known as an Actualized Fantasy Screen Waster (not to be confused with a Virtual Reality Screen Saver). The DreamScape Demo given at the Apple World Wide Developer Conference flies through its many features.

These are some of the concepts around which DreamScape was designed.

  • Constructive Experience.
    Open ended set of tools, rules, and resources that you can use together in creative ways, resulting in both predictable and unexpected behaviors.
  • Nurturing Environment.
    As opposed to a Killer App. Provide creative people with fertile ground in which to plant their seeds.
  • Dynamic Extensibility.
    Author new rooms and parts on a regular basis, that people can plug together and dynamically load at run time.
  • Distributed Multimedia Publishing.
    Distribute suites of plug-in rooms and parts on-line, by using KMP as a WWW Helper Application. Distribute bulky media on CDROM or via FTP, that is referred to by light weight up-to-date plug-in parts published regularly on Web servers.
  • Transparent User Interface.
    Content is more important than control panels.
  • Direct Manipulation.
    Graphical representation, intuitive response to input, modeless, continuous feedback.
  • Multithreaded Animation.
    Everything on the screen is happening at once. You don’t have to click, stop, and wait for an animation to finish before doing something else.
  • Gestural Interaction.
    Directional pie menu “flicking” gesture for moving between rooms, connecting and disconnecting maps. Throwing gesture to move objects around dynamically. Painting tools effected by gestures. Butterfly and robot apply gestures to the parts they’re holding, in the same way you do when you drag them around.
  • Navigation Metaphor.
    Consistent two way links, maintained by the editable map view, so you can remember your way around. The map editor interface makes it easy to build topologically flat maps, but still allows you to make tangled un-geographic “hyperspace” links.
  • Simulation Metaphor.
    Continuous physical processes like motion, gravity, and friction are simulated, so the number of states the system can be in is virtually infinite. Spatial navigation without simulation only has as many possible states as spaces (“you are here”).
  • Deconstructionist Interface Model.
    Object oriented design techniques deeply effect the very nature of the interactive experience. Whatever that means.
  • Users and Agents on Common Ground.
    You can interact directly with simulated agents, because you’re both part of the same environment. The butterfly can pick flowers and paint with them, as easily as you can. The painting tools respond to the gestures of whoever’s holding them, human, butterfly, robot, or any cyborganic combination! You can even pick up a waving robot arm, grab the fluttering butterfly with it, shake her around, and paint with the flower she’s holding! The flower, or whatever the butterfly has ahold of, will respond to the combined gestures of you, the robot arm, and the butterfly! Fortunately, she can’t pick you up and paint with whatever you’re holding — that would be taking it too far.
  • Plug-In Authoring Tools.
    Dynamically loaded map window lets you jump around and edit room connections. Dynamically loaded sets of painting tools with themes, that draw in interesting and appropriate ways, in response to gesture.
  • Director as ScriptX Authoring Tool.
    Leverage off of ScriptX’s Director Importer Toolkit, so artists can use Director for what it’s good at, assembling animations and positioning registration points, then easily import their artwork into ScriptX, without programming. So it’s easy to make all kinds of animated parts with sound effects and moving registration points, and painting tools that scatter images around like the “Image Hose” in Painter, that all plug together in wonderful ways.
  • Finder as ScriptX Authoring Tool.
    Leverage off of the capabilities of the Finder and File Manager as much as possible. People know how to use the Finder, and it’s very good for certain tasks, like naming and organizing directories, source and media files. Organize projects in directories and files, which work across all platforms, instead of storing source code and media in some special database format. ScriptX build scripts automatically process everything in certain directories, so you can just put your stuff into place and run a script, without programming.
  • ScriptX as Web Authoring Tool.
    Coming soon: “Save as HTML”! Check out the ScriptX Web Module Documentation.

--

--

Don Hopkins

User interface flower child. Pie menus, PizzaTool, SimCity, The Sims, Visual Programming, VR, AR, Unity3D / JavaScript bridge.