Tuesday, January 22, 2008

metaverse memory: lsl1

I just had a chance to read James Au's new book, "The Making of Second Life." It was a fun read, but like any collection of memories, it captures only a tiny slice of the events that went into making Second Life. So, I think it would be fun to make a semi-regular part of this site different moments from my memories of the first 7 years of Second Life.

So, my first metaverse memory:

Around August of 2001, back when Second Life was called Linden World (note 1), there was no scripting language in SL. Primitar was about to replace the spaceships and floating eyeballs that were the original avatars and James was doing the first major UI revamp so that we could add to the world without shooting. The entire team had been debating how to add behavior into the system for months, with Philip arguing that we should just use physics. Philip had some really good points, because if we were able to use Havok for all of our behaviors, residents would be able to gauge the complexity of an object by just looking at it -- like mechanical systems in the real world -- and we wouldn't have to divert scarce resources into a project that could take significant time and effort. Mitch was also an advocate of visual complexity representing behavioral complexity, and I think there was something to that idea.

Unfortunately, Havok running on Pentium 4 servers was nowhere near powerful enough to represent complex systems in a general way. We had built some simple slides and teeter-totters, and while these were good geek fun, they didn't extend to create the kind of behaviors we all knew the world needed. But, I also believed that Philip was right. We just didn't have the development resources to divert a large number of people to build a scripting language.

So, I decided to crank one out in a night. Andrew and I both did semi-regular all nighters during those early Linden days -- including a memorable night when Andrew managed to lock me out of the room my keys were in and set the alarm, but that's another story. I am a huge believer is limiting developers to 40-50 hour weeks in order to maintain long-term productivity, but it is fun to occasionally proving you can still create something in a night. A simple language seemed like a perfect fit.

LSL (or, what became LSL1 when I wrote LSL2 to replace it) looked a lot like assembly, because this allowed the least amount of work to go into the parser and compiler. It had some of the functionality of the LSL2 -- for example, it could detect if you clicked on an object or a collision -- and had functions. It also was already event driven, an approach central to LSL2. Most importantly, it was working just in time for a Friday "Show and Tell"! I built a simple garage door, where a box would move from open to closed when you clicked on it, as well as some rotating objects, and demonstrated it.

Everybody was jazzed and after some discussion, we agreed that it should get rolled into the code. Philip immediately combined LSL1 with the physics engine to build the wind chimes that graced the original starting area. It would be about 8 months before I found time to revisit it and build LSL2 (note 2), the scripting language used in SL today. Finding time to build LSL2 became critical because our Alpha residents were building content so quickly in LSL1 and we knew that we couldn't support LSL1 going forward.

But that is a story for another day.

(1) There have been various reports of where the name Linden World came from. Sadly, that name was my fault. When I gave my signed offer letter to Philip, we met down at Accel's office in Palo Alto. One of the best parts of the early Linden offer letters is that Philip wrote them in a relatively informal style that perfectly captured his excitement about Linden. If I recall correctly, it had a wonderful phrase about how happy he was to be hiring me and that we were going to change the world. I was excited and worried, since I was walking away from what I knew -- game development -- and trying something quite new, and a bit intimidated by the whole Accel VC vibe. Philip set me at ease and introduced me to several of the Accel partners, including Jim Breyer. I handed him the paperwork that would put me on a new path and he shook my hand, saying how much fun we were going to have building this new world. I responded with "Yes, building Linden World is going to a blast." I paused. "But, let's never call it that!" Unfortunately, the name stuck in early discussions with Andrew and Frank -- and was cemented thanks to Frank's "Welcome to Linden World!" audio sample -- despite all of us agreeing that it was a horrible name. It wasn't until after Demo, the hiring of Hunter and Robin, and the move to 2nd Street that we were able to really revisit the name.

(2) LSL2 was designed and built over the course of about a week in early 2002. I had done some general Lex-Yacc homework before that, as it had been years since I had used them, and we did one meeting where we brainstormed what the structure of LSL2 should be. The initial LSL2 implementation didn't have lists. An extremely broken list implementation was added a few months later and then debugged for months. LSL2 will soon be running on the Mono open source CLI engine, which will make it much faster. For all of its challenges -- nobody is harder on LSL2 than I am -- it is still satisfying to know that over a million people have collectively written over 2.5 billion lines of code with LSL2.

5 comments:

Tim Allen / FlipperPA said...

Despite having some of the same inconsistencies I've seen in other languages, and some obvious missing pieces, I've been amazed by how much can been done by LSL2. I'm looking forward to running on mono, and hope some of the limitations people have had to hack around could be lifted. LSL2 is going to be around for a long time.

Jonathan Bishop said...

YACC - Wow. Now that is a "blast from the past". It has been 20-25 years since I used YACC. Probably not how I would do a production language, because it can't take advantage of code optimisation opportunities (if I recall correctly), and doesn't produce the worlds most efficient 'compiler' but not a bad idea for language design testing because it, at least, imposes some formalism on the grammar and gets an interpreter layer up quickly.

At one of the universities at which I taught, we used language definition as the core step in the problem solving process across multiple courses. I think this was more by accident than design, as it was reflective the natural skill sets of the academic team at the uni at the time, but as a design paradigm it worked outstandingly well.

Essentially the idea is that, faced with a set of computational problems, you first design the ideal language to solve that problem set, then write an interpreter/compiler or function library for that imaginary language. Lastly you encode the solution to the original computational problem set in the language you have designed.

The approach produced some of the best programmers I have ever worked with, capable of building reliable, extensible code very quickly. It also made writing interpreters and compilers second nature.

As an approach it pre-empted and predicted later ideas of Design Patterns (although we did not call it that, then), because the whole approach was about re-usable patterns, and layer abstraction, expressed as language grammars and function/object layers rather than objects.

It is still the core approach that I use, and essentially it is the concept implied whenever someone decides to build a script language for their application library to allow re-use and extension of the central code base. Although, few programmers think like this, and consequently the script languages created are, too often, an after thought to surface some core code library, rather than the dictater of the code library's required functionality and structure.

I agree with flipper, LSL has proven remarkably versatile, and as I have already stated, I have a great affection for it's fundamental idea. I would like an LSL3, however, that preserved the 90% of LSL that is cool, but reworked the 10% that needs to be rethought. I think the interrupt structure, inter-prim messaging, and dataserver implementation (and syntactical/semantic design) need attention. State definitions would be more efficient (from a coding perspective) if they inheritted from other states (like objects), introduction of eifel's programming by contract idea would reduce bugs, call-by-name (lazy evaluation) might improve offer some function execution advantages in large list handling, prim faces control and rotation needs simplification, the agent/object/prim interrogation facilites are untidy, and script concurrency would be helped by better script synching elements (even a mutex would or "wait-on" thingy would help) and a sweep of the basic language elements to add in those that reduce coding (like case/switch, arrays, inline if-then-else, stacks and queues, etc).

I think one of the problems LSL did not adequately solve was the events. To many scripts resort to polling and timers to detect critical events, and unless I am missing something about the server architecture, this strikes me as expensive in resorces.

A rework of some of this (particularly interrupts) would imply a rethink (I suspect) of prim properties. Transferring the responsibility for notification from the sensor to the sensee (at least for some of the events) - if that makes sense - but eliminating the need to poll.

Lastly, a wider range of gent to object interrupts (beyond essentially touch/sit/pay) would considerably expand the UI opportunitites, and reduce the need for encoded menus in applications.

Hmm. I guess this comment got a bit offtrack from the original post which was about memories from SL - but, heh, you mentioned LSL. Feed an addict his weakness - you gotta expect the inevitable response.

Dave Briccetti said...

Very enjoyable reading. Do continue!

Unknown said...

Cory

One weekend. Add associative arrays.

That's all we ask ;)

cory ondrejka said...

Not my job anymore :-)