Friday, December 31, 2004

Tricky portal/pointer code

I am working on having the user's laser pointer do the right thing when you pick through a portal. What should happen is the laser beam should break into pieces when it transitions through a portal. For example, now when you select an object in the mirror, the pointer simply points directly to the object from the avatar instead of bouncing against the mirror first. If you attempt to manipulate an object that is in a different space on the other side of a portal, the laser points to the position in the current space of where the object is in the remote. This looks bad and can be confusing.

The main reason I am doing this is in support of the CAD system, as picking through a portal is a central part of that UI, and it really needs to work in an appropriate way. Unfortunately, this is kind of complex. What has to happen is I have to add a laser segment into every space that the pointer traverses a portal to. And of course, this must be replicated - and it needs to be removed after every local render. My concern is that this may be a very expensive process and not worth the resulting payoff. I know there might be some speed enhancements by keeping the remote laser segments around longer, but I really don't want to worry about that yet.

Thursday, December 30, 2004

Artie Shaw

Somewhat off topic, but Artie Shaw - the great bandleader and clarinetist, died today. He was 94. If you haven't heard him and his orchestra play, run out and get his Self Portrait Anthology. I was simply astonished when I heard it the first time - particularly disk two. This guy rocked before there was rock.

Ghost objects

Wicket requires that a normal TSpace be rendered with additional interleaved objects that are not actually in the scene. These are what I call "ghost" objects. They are not in the TSpace hierarchy, but they can be rendered and used as if they were. They are actually owned by the TPortal in the case of the filters, which allows the programmer to render a scene with additional content when scene through the portal. What this means for Wicket is that the CAD tools, such as the 2D draw surfaces and edit boxes would only be displayed through the portal.

A related issue is removing objects in a scene. This tends to be a bit more complex, as it would require every frame to be checked to see if it matches a particular characteristic. This might be better done as some kind of global flag that the objects themselves can test against.

Tuesday, December 28, 2004


OK - didn't get much done today after all (day is not done yet though). I spent today working to fix my son's machine - 15 viruses, 95 different malwares, adware, etc. Our internet access was grinding to a halt, so I put a log onto the router and found out that his machine had been zombied - it was looking for open IP addresses to cause even more trouble. I ran Ad-Aware first, and didn't find any more than the usual suspects. Then I ran Spybot Search & Destroy, which found a few things - maybe about 3 or 4, but nothing that I hadn't seen before. Then I installed Spyware Doctor and this discovered about 95 different malware variants. I thought that this had killed the zombie problem, so I went back to work. A little later I noticed that the zombie was still quite alive, so finally I ran Norton Antivirus. This discovered a host of problems, some of which I am still dealing with. I am pretty sure that one of these is the problem, but if it isn't the only thing left is to wipe the disk and start over.

The moral is... don't let teenagers have access to the net.

Wicket Day 1

I need to make the user's laser pointer bounce properly in the mirrors and through portals. There are two reasons for this - the first is that it looks crappy to other users when you select an object through a mirror and the laser points in some random direction. The reason this happens is the selection is occurring in the frame of the space on the other side of the portal, but is being drawn in the local space. This can only be fixed by breaking the laser into pieces, one for each portal it traverses. The problem with this is it means I need to track all of these laser segments as they render in the remote spaces. I do something similar now with the Avatar down ray. I add a "foot frame" to whatever the down ray finds. This is how I have the avatar move with whatever it is on top of. I just add the delta translation of the foot frame to the avatar's position.

The second reason I need to track the bounce is that a portal will be able to add a task to the pointer when it picks through. If I have multiple portals, I will add multiple tasks - though I have no idea what this means in practice.

I have been thinking about this problem for way to long, and it is time to "Just Do It" tm. I took my Ritalin, killed the Spider Solitaire, the kids have left the building, and now I am ready to roll...

Tuesday, December 21, 2004

3Dsolve and Croquet

3DSolve is developing an application on top of Croquet. See more about it here .

Friday, December 17, 2004

Back from DC

There was a lot of interest in Croquet in DC. Had a lot of great conversations and had WAY too much to drink with Rick McGeer. But neither of us had to drive home and the scotch was pretty good.

Now to get the road map done and then code code code...

Monday, December 13, 2004

What Next?

I have one more bug to fix, then I am on to the Croquet Road Map. I have plenty of notes and things, so it should be pretty easy to put together once I start. Unfortunately, I don't start until Friday, as I will be in Washington DC thru Thursday evening. Once THAT is done, then I get to work on Wicket.

The big missing piece is the documentation. I REALLY need to do this, but it may have to wait till January. I may have some major revisions of how the system works anyway, so it is just as well.

Sunday, December 12, 2004

Performance issue ... solved

I finally figured out what was going on with Orion's performance issue, and why it was hard for me to find it. Turns out that Andreas modified the #stepTime method to return 20, instead of 0 as it was originally. Later this was modified to return 1 if the highPerformance setting was enabled, which it usually isn't. When I set this flag in the preferences, I had essentially the same frame rate with the current Jasmine change set as with Orion's older pre-change version.

I speculate that the reason he had an increase in frame rate when he put another morph on top of the TeapotMorph was that the other morph was updating at fullspeed, which would of course force the underneath morph to update at the same rate.

This was hard to figure out, because I was always testing with larger worlds on machines that were slower than what Orion has. That is, I couldn't usually even get close to 40 Hz update rates with what I was usually doing, so the #stepTime didn't really matter much, as I was running less than this speed. The reason there was such an unevenness to the performance that Orion also noticed was that we use the morph render time to also update and process the future and remote message queue. The longer the delay, the more messages that would qualify for computation.

Saturday, December 11, 2004

To Do:

I am hitting the wall again - lots of stuff to do.

- Figure out Orion's performance problem. Even with a very simple world, we have some large cost thing going on now that wasn't there a few months ago.
- Fix the bugs in Mad Hatter - the Sierpinski bound sphere is in the wrong place
- Write up the Croquet Road Map. This is essentially a listing of the high priority items that we have.
- Write the new Wicket demo. See more about this below.

And I need to have it all done by the end of January. Actually, the road map needs to be done by the end of December. As Crichton used to say: "Butt in the seat".

Thursday, December 02, 2004

Fixing and finding bugs

I want to finish up the bug fixing for the old Wicket editor. I don't plan to use this for the next version, but I am interested in why it went south so badly. Also, I will look into the texture problem with the duplicated textures. Finally, I need to figure out why the bound sphere for the sierpinski in MadHatter is in the wrong place. I think that for some reason it is not getting updated, so it is still at 0,0,0.

I completed the paper for the C5 conference. I think the ideas are pretty good, though I would have liked to discuss the conceptual details a bit more (and a bit better). It turns out that the MVC model is very similar to what we came up with to solve modeless interactions in collaborative 3D. Here is an interesting overview of MVC by the creator of the idea:

MVC History

Another important early paper was written by Adele Goldberg and Dave Robson entitled:

"A Metaphor for User Interface Design."

Unfortunately, we simply could not find a web reference to this paper which was published as part of the U of Hawaii Symposium on System Science. Ted Kaehler was kind enough to provide me with a digitized copy. Alan was also surprised that this was so hard to come by, and suggested that we should have an online repository for some of the important papers in the field (at least the ones that we think are important).

Friday, November 26, 2004

Filters and Tasks in Croquet

I have started writing my C5 paper and I have found some very interesting related papers. Probably the most interesting is a Xerox PARC paper from '93: Toolglass and Magic Lenses: The See-Through Interface
written by Eric A. Bier, Maureen C. Stone, Ken Pier, William Buxton, Tony D. DeRose. From the abstract:

"Toolglass(TM) widgets are new user interface tools that can appear, as though on a transparent sheet of glass, between an application and a traditional cursor. They can be positioned with one hand while the other positions the cursor. The widgets provide a rich and concise vocabulary for operating on application objects. These widgets may incorporate visual filters, called Magic Lens(TM) filters, that modify the presentation of application objects to reveal hidden information, to enhance data of interest, or to suppress distracting information. Together, these tools form a see-through interface that offers many advantages over traditional controls. They provide a new style of interaction that better exploits the user's everyday skills. They can reduce steps, cursor motion, and errors. Many widgets can be provided in a user interface, by designers and by users, without requiring dedicated screen space. In addition, lenses provide rich context-dependent feedback and the ability to view details and context simultaneously. Our widgets and lenses can be combined to form operation and viewing macros, and can be used over multiple applications."

These ideas were applied to 3D spaces in this paper: 3D Magic Lenses by John Viega, Matthew J. Conway, George Williams, and Randy Pausch. This does a nice job explaining the visualization capabilities of a both a 2D magic lens in a 3D space and a 3D box lens - that is, the contents of a box are rendered differently than the elements outside the box. The also cover the WIM - world in miniature concept that we implemented in Croquet.

The major additions we have are in the model of interaction - that is using these objects as toolglasses as described above, and in managing them as part of a collaborative system. Further, I think that this UI model is exactly the right way to create complex applications in Croquet.

Wednesday, November 17, 2004

Wicket in Python

I have decided to write the Wicket editor in Python. There are a number of good reasons for this:

- We need to have a number of alternative languages available in Croquet. It would be a shame for people to get turned off of it just because they don't want to learn Smalltalk.
- This is a forcing function for us to get the Python compiler done so that I can begin work. Andreas thinks he can have it by Monday.
- I don't know Python. For some reason, I don't seem to have much problem switching languages, as they all are pretty much the same to me with slight differences in syntax. APL is a bit different, but since it was my first real language it seems quite natural to me. In fact, I really miss it's array/matrix handling.
- It would be nice to have a substantial application running in Croquet in another language as part of the demonstration of the systems capabilities.

The Wicket architecture is going to be really neat. It is the first application that will utilize the Replicant/Interactor/Task model and the new UI that we have come up with.

Sunday, November 14, 2004

To Do

There are still a few major gotchas in Jasmine that need to be sorted out before I jump into the Next Big Thing. This list is far from complete, but at least you can see what I am looking at doing.

- Removed TObjects do not go away sometimes. The reason is they may be sending themselves future messages, which in turn send future messages. Hence, these loose objects are hanging around simply by keeping themselves in the future message queue.

- The Wicket CAD system is in bad shape. For some reason, the corner handles are in the wrong place.

- Sometimes, when we first connect, an error occurs because before the connection, we are sharing the same TAvatar. The complicated thing is that this avatar is removed from the scene graph but doesn't know it yet.

- There is a very noticable performance hit sometimes after we connect. Andreas just upgraded the MessageTally system so that I can better track where our time is going.

Hope to have these figured out in the next day or so.

Thursday, November 11, 2004

Broken Collaboration

We currently have a bug in Croquet where if you are connected to a group of peers and bring up the pop-up button menu, if you click on the top left x to make the pop-up go away, the remote parties get an error because they do not have this object. The pop-up is not a replicated object, hence the meta message that gets sent has no where to go. This is where the TeaTime architecture will be required. In this case, all of the overlay objects will be placed into the users personal TeaParty - hence it will not generate any replicated messages. Until this is in place, we will probably have to ignore messages that are sent to non-existent remote objects.

Monday, November 08, 2004

I am really back

Back from Boston where I met with Andreas and David R for a couple of days. We made significant progress in planning for the next major steps in Croquet and in understanding the nature of the dichotomy between TeaTime and the meta architecture - why one approach seems to be better for some things and the other approach seems to be better for other things. This understanding led us to a very useful insight that will have a direct impact on the nature of the architecture moving forward. I will attempt to discuss this further later on.

I am also back from being really sick. Today I feel -almost- normal, so I hope I can catch up on my work. My wife points out that this never happens. No matter how much I get done, I always feel like I am behind. Oh, well...

So the major tasks in front of me at the moment are:

- Enhance Alan's demos for the Kyoto prize. I need to get this done by Wed. Preferrably get it done today.
- Write the C5 paper. This is due on Nov. 15. We just decided on the topic on Friday and I need to actually write some code for this.
- Build Wicket 2. This is part of the C5 paper, but is more important to have for the actual talk in January.
- Debug Croquet. There are a lot of things that need to get done there.
- Minimal Croquet Documentation. This will have to wait a bit, as I have more pressing matters (I know you all hate me for saying that, but there it is...)

At least I feel better now, so I can get this done. I didn't get anything accomplished except for the Boston discussions last week.

Onward, onward...

Tuesday, November 02, 2004

Been sick - gettin better

I haven't posted for a while since I have had a terrible respiratory problem. I think I picked it up on the way to Vancouver. I am slowly getting better, but haven't had much energy to do much more than listen to CNN. Today I started coding again, but tomorrow I fly to Boston to work with Andreas and David to plan for integrating TeaTime as well as prioritize a number of other missing pieces of Croquet. Should be back to normal soon.

Thursday, October 28, 2004

Turing Lecture - Oh Canada

Originally uploaded by Croqueteer.
Here it is - the grand finale. All we did here was slowly turn on the flag texture opacity, while at the same time we turned off the wireframe's. While we were doing this we played the Canadian National Anthem. Why Canada? The talk was in Vancouver, it's a good song, and the Canadian flag size is an exact 2 to 1 ratio making it an ideal flag for building bridges out of.

The code is described in some detail in earlier posts - nothing was done here except some hacks for scripting and setting the initial conditions. Otherwise, this is pretty much the TTapestry object that I created earlier.

Turing Lecture - Release

Originally uploaded by Croqueteer.
Here we see the bridge breaking away from its moorings. In this case, we had set any mass that we did not want to move to have a mass value of 0. This meant that it's location would not be modified in any way. To release it, all we did was set it to a non-zero value, and magic happens. The other thing we did was set the left top mass initial location to be in a different location. When this happens, AND the mass is 0, the mass will move -slowly, to this location if it is different from whereever it is currently.

Turing Lecture - Add Wind

Originally uploaded by Croqueteer.
This adds a wind force to all of the masses in the scene. This wind is generated as a vector centered at the tip of a cone and following the cone. Put your arm out in front of you and draw a circle. This wind vector is your arm. At this point, the bridge starts waving around in space reminding us of the Tacoma narrows bridge.

Turing Lecture - Change Spring Constant

Originally uploaded by Croqueteer.
This script allows us to modify the springs that make up the edges of the bridge. Remember that the spring doesn't generate any force when the x in -kx is 0. x in this case is the delta from the spring at rest. That is what this computes. Here we changed the k value from -1400 which is a very stiff spring, to -400, which is quite a bit softer. Less force is generated from the same delta x. Note that the bridge is now sagging significantly more now.

Turing Lecture - Add Gravity

Originally uploaded by Croqueteer.
This is a (simulated) scene from Alan's Turing Lecture. This is a pseudoscripting system that Andreas put together last week to match the look of the etoys system and present the code in a bit more readable form. Otherwise, this pretty much the same code for the flag as seen below. This is real code - we are indeed modifying it as the system runs and not only that, but it is being done collaboratively, so if we had mutliple machines running this they would all recieive the same new code and compile it.

Here we are comuting the acceleration of the mass from the force and then computing the new velocity and new mass location from this. The last line sets the initial force to a downward gravity of -2.5. The other two values in that vector are there to create noise.

Wednesday, October 27, 2004

Back from OOPSLA

Just arrived back home. I will write about the demo that we did for Alan's Turing Award Lecture tomorrow. Alan received a standing ovation for his talk, and I must say it was the best one I have seen him give. It was concise and quite powerful. The demos he did at the end were a strong demonstration of the truth of his words. I was inspired. Time to take back the night...

Test Flickr to Blog

Originally uploaded by Croqueteer.
I have a number of images I want to include in these discussions, and Flickr seems to be a convenient way to do this. Full disclosure: One of my friends and colleagues - Frank Boosman - is on Ludicorp's board, but that has nothing to do with why I am using it. It is convenient.

Friday, October 22, 2004

Turing Demo

I have been working on a new Croquet demo for Alan's Turing Award talk at OOPSLA next week. I just tried it out on my son and his friend, and they were quite impressed, so I think it is going to go over very well. I won't talk about it any more here, because I want it to be a surprise for people, but once it is done, I will post it so everyone can play with it.

I have two major things left to do before I jump into the documentation again. First, I have to fix the Wicket CAD system - for some reason the handles around the TEditBox are now in the center. Very strange, and I am pretty sure this was fine when I used it to test Jasmine's recursive meta fix.

The other thing is there are still a few loose ends on some of the objects not working properly for multi-user. Will fix that soon too.

I got four hours of sleep last night. This is fun, but I am getting old....

Thursday, October 21, 2004

I need...more speed...

So I fixed a nasty bug in the rendering code that was causing everything in the Mars and Aqueduct worlds to run 1/2 speed. What was happening was the models that make up these scenes were being installed into the TQuadTree object twice when it was being constructed. This means every single element got rendered twice. Hence, not only did it seem like it was running at 1/2 speed - it probably was.

A TQuadTree is an object that breaks space up into four quadrants - I call them top left, top right, bottom left, and bottom right. Each of the quadrants is actually a TQuadTree itself and is in turn broken up into four quadrants. In theory, this recursion can continue infinitely, but in reality, I stop after a depth of 5. Also, if a quadrant would otherwise be empty, it is set to nil.

We actually create the TQuadTree object with the act of dropping a collection of frames into it. Each of these frames has it's own boundSphere around it, and we compare this to the size and location of each quadrant. If the object can't be put in one of the sub-quadrants because it is too large, we just leave it at the containing quadrant. Thus, each sub-frame eventually comes to rest at the quadrant that best approximates it's size.

So why deal with QuadTrees? The idea is that an object is easier to find (for picking or rendering) by traversing this tree of quadrants. Objects are placed into the TQuadTree based upon location and size. For example, if you need to find a point directly underneath you, you already know which quadrant you are in, so you can test just that one. If that fails, you can test it's subquadrants, etc., until you find an object to stand on. This is ignoring the fact that objects tend to overlap quadrant boundaries, and in fact I deal with this as well. The TQuadTree is what is known as a loose quadtree. That is a quadtree that allows overlaps, but requires that you test all of the edge quadtrees as well. This works surprisingly well, as we only need to put an object into the quadrant that contains it's center point. If you don't use a loose quadtree/octree method, you can use a strict method, but this requires you to duplicate the object in all of the quadrants it overlaps.

The other win that quadtrees like this gives you is improvements in rendering speed. If a quadrant is visible to the camera, then it is quite probable that the contents of that quadrant will be as well. More importantly, if a quadrant is NOT visible, then we have a guarantee that it's contents are not visible. The same overlapping/neighboring quadrant test applies to rendering as well.

One way to think of the process of constructing an octree is that of a collection of sieves- one on top of the other - with the ones with the larger holes on top, and smaller holes as you go down from there. The objects that make up the scene fall through the larger ones until they no longer can fit in the lower ones. When the sorting is all done, each object is at its proper location in the sieve.

One other benefit that loose quadtrees give you is it is much easier to move an object around in one of these. Since only one copy of the object exists in the tree - we need only move it from one quadrant to another when it's center point has moved across the boundary between them. Bookkeeping is extremely simple.

Tuesday, October 19, 2004

Rendering Speed Problem

The Jasmine release of Croquet seems to be about half the speed of the Solar version. Andreas said he thought it might be due to the objects like the TFlag constantly running in the background, but I don't think so. In addition, the PC version seems to be running much faster than the Mac, where in the past they were about equivalent. Again, not sure why. I don't think that the rendering pipeline is that much different between Jasmine and Solar. I thought it might be a texture issue, but turning off texturing entirely makes little difference in performance. The good news is clearly once we fix this, everything runs a lot faster.

Sunday, October 17, 2004

Blogger = Poor formatting

Blogger does a particularly poor job of formatting just about everything. It is certainly easy to use, but the quality of posts, especially things like code, and the way it handles emailed blogs is unacceptable. If anyone knows a better system, please let me know.

As an example, spaces are as important in a sentence as the words.


Unfortunately, I can't show you an example where multiple spaces add to the meaning of a sentence, because BLOGGER STRIPS THEM OUT. What is worse, they had to write code to do this, as the text would have printed just fine otherwise. In fact, it looks fine in the editor. This is stoopid.

How to render the Flag

Croquet uses OpenGL so rendering the TTTapestry is just a series of OpenGL calls. You can find this code in the recent Croquet updates as well.

The basic idea is the masses are objects that include their position in space, the normal that is computed from their neighbors, the texture u,v location which are all used in rendering, and the summation of the forces from the springs, gravity, and wind. The mass position is an obviously useful thing to have around. This is used both to render it here and to determine how much the TSpring is stretched to determine it's restoring force.

The normal is used by both the wind vector to determine how much of the face of the flag is facing the wind. That is, a piece of cloth that is perpendicular to the wind feels a strong force, where one that is parallel doesn't feel much at all. It is also used in lighting the flag, as the amount of light at this location is determined in much the same as the amount of force from the wind is.

The texture u,v coordinates are usually a number between 0.0 and 1.0 and determine what part of the flag's texture corresponds to this mass location. The texture is then stretched between the other mass locations and this one.

This method uses a triangle strip method. It is actually kind of a zig-zag like this:



We have to make a number of top to bottom strips like this to complete the flag, so it looks a bit more like this:

-------- --------
------ ------
--- ---
-------- --------
------ ------
--- ---

TTapestry>>#render: ogl
"We always pass in the OpenGL object when we render"
| index m |

ogl glDisable: GLCullFace. "we want to render both sides"
texture ifNotNil: [ texture enable: ogl.]."activate the texture"
1 to: xsize-1 do:[:i | "this is left to right"
wire ifFalse:[ ogl glBegin: GLTriangleStrip.] " if this is wire frame"
ifTrue:[ ogl glBegin: GLLineStrip.]. "or if it isn't"
1 to: ysize do:[:j | "draw the strips vertically"
index _ (i-1*ysize)+j. "location of the mass in the big array"
m _ masses at: index.
ogl glNormal3fv: m normal. "computed from nearby masses"
ogl glTexCoord2f: m uv x with: m uv y. "texture coordinates"
ogl glVertex3fv: m location. "continue line at 3D location of mass"
index _ index +ysize. "index of the mass to our right"
m _ masses at: index.
ogl glNormal3fv: m normal.
ogl glTexCoord2f: m uv x with: m uv y.
ogl glVertex3fv: m location.

ogl glEnd. "stop rendering the triangle strip"

"If we are rendering in wire frame, clean up the edges, otherwise we have
a zig-zag like shape."
wire ifTrue:[
1 to: xsize do:[:j |
ogl glBegin: GLLineStrip.
1 to: ysize do:[:i |
ogl glVertex3fv: (masses at:(j-1*ysize)+i) location.].
ogl glEnd.
texture ifNotNil:[texture disable: ogl.].
This was test code to render the springs to see if these make any sense...
they do now.

springs do:[:s |
ogl glBegin: GLLineStrip.
ogl glVertex3fv: s mass1 location+(0@2@0.3).
ogl glVertex3fv: s mass2 location+(0@2@0.3).
ogl glEnd.
This was test code to display all of the normals on the flag.

masses do:[:ms |
ogl glBegin: GLLineStrip.
ogl glVertex3fv: ms location.
ogl glVertex3fv: ms location - ms normal.
ogl glEnd.

"return OpenGL back to it's standard approach of culling back faces"
ogl setCull.

Saturday, October 16, 2004

Flag Time to Run

Here is something interesting. I compared the two compute engines of the old TFlag and the new TTapestry and found the following:

tf := TFlag new.
tt :=TTapestry new.

( the results are in milliseconds)
[1000 timesRepeat:[ tf step ]]timeToRun 8608
[1000 timesRepeat: [tt testCompute]]timeToRun 9528

[10000 timesRepeat:[ tf step ]]timeToRun 80553
[10000 timesRepeat:[ tt testCompute]]timeToRun 92868

I presume that what this means is the much simpler code of TTapestry, which yields nearly identical qualitative results does not take that much longer than the array juggling that TFlag has to do.

A fifteen percent increase in compute time is a small cost to pay for the code being so much more readable. Also, though I can't imagine where I could speed up the TFlag computation, as it is so complex, I am sure I could easily find a few additional cycles in the TTapestry. But then, perhaps I am missing something?

The new classes are posted as Croquet updates. See TTapestry for how to use.

Thursday, October 14, 2004

At Jawjaw Tek

Alan gave his dry-run talk for his Turing Award talk later this month (which was excellent by the way). I was supposed to demo the mass/spring model I did with him at the end, but did not realize he was waiting for me to let him know I was ready - and I was waiting for him to let me know when to come up to do it. Oh well. I expect the demo will be in great shape for the next talk. Besides, I think his talk was actually quite well done without my demo at the end. I think it might have broken his stride.

The demo is actually quite simple. There are three objects. What I call a TTapestry, which is the UI and rendering of the system, a TMass, which holds a position, summed forces, and a mass (usually 1.0), and TSpring, which connects two masses.

When initialized, TTapestry creates a grid of TMasses, roughly in a square, and generates a collection of TSprings, each of which is iniitalized with two masses that can have influence on each other. All three of these have a #compute method. The TTapestry compute sends the other two compute messages to the collection of masses and then springs.

TTapestry>> #compute

self addWind.

springs do:[ :s | s compute. ].
masses do:[ :m | m compute. ].

self future: 20 perform: #compute.

the #addWind message just adds another force to the masses from a virtual wind.

The TSpring>>#compute uses the standard -kx force computation as below:

TSpring>> #compute

| v n k |

k:= -200.0.
v _ (mass1 location - mass2 location).
n _ v normalized * rest.
v _ (v-n) * k.
mass1 addForce: v.
mass2 addForce: v negated.

All that this is doing is determining the vector distance between the two masses, subtracting the rest distance (where the x in -kx is zero) and then multiplying the rest by k. We then add this force and its equal and opposite reaction force to the appropriate masses.

Finally, we compute the effect of the forces on each mass:


| g accel t |
mass ~= 0.0 ifTrue:[
t := 0.05.
g := 0.0@-2.0@0.0.
force := force + g." add the gravity"
accel := force. " mass = 1.0"
velocity := velocity + (accel * t). "acceleration increases velocity"
velocity := velocity - (velocity * 0.1)."damp velocity"
location := location + (velocity * t). "change location"
force := 0@0@0. "clear force"

if the mass is 0.0 we don't do anything, as this means the mass is a fixed location - like the corner of the flag.

We could use the actual elapsed time here, but I am just using an artificial one, which I am setting to 0.05 of a second. I am presuming that the mass is equal to 1.0 so I don't have to divide to compute acceleration (f = ma, hence a = f/m).

Acceleration causes a change in the velocity, and velocity causes a change in position, so now we have moved the location of the mass.

This last line is very important. Now that we have resolved the forces from this time segment into an action, we need to clear the force vector. If we don't, this force value will continue to grow, which causes the system to become unstable.

That is all there is for the masses and springs. Really. The TTapestry adds a wind, but this just results in another force being added to the masses. What I find so interesting is that these two extremely simple objects generate such interesting behavior.

The only other interesting thing is the TTapestry>>#render:, but for some reason I screwed this up, so need to thing about it a bit before I post it here...

Wednesday, October 13, 2004

Off to Georgia

Alan is giving a talk at Georgia Tech tomorrow and asked me to come along for the ride. Things look pretty good - I think we will have a much more robust version of Croquet by tomorrow than Solar ever was. By the way, Solar was our old war horse demo platform. All of the neat little demo apps we have in Croquet were built to show off in the Solar version. I called it Solar because it has a neat model of the Solar system in it. I tended to keep track of the versions based upon whatever new thing I had built in it. There is no Jasmine app - yet.

Alan wants a demo that is kind of a cross between the flag and the CAD system. For tomorrow's talk...

I have been thinking about this for a bit. I have some interesting ideas which I will probably write about later.

Tuesday, October 12, 2004

Jasmine Debugging

I must have killed a dozen bugs today already. Most of them are between the crack bugs - that is, bugs that were created by porting the MadHatter architecture onto the Solar replication model. Nothing fundamentally wrong, just tracking them down and checking with Solar on how the objects computation should be replicated.

There is one potentially serious problem that I am in the middle of fixing. When an avatar traverses through a portal into another space, currently the remote version of the avatar is not making the transition. The reason was pretty simple - the transition was never sent remotely. The problem is that we send the following message:

avatar future: 0.0 perform: #goToPortal:transform: withArguments: { toPortal . trans }.

which is in effect telling the avatar to jump through the portal asap. What we really want is

avatar meta future: 0.0 perform: #goToPortal:transform: withArguments: { toPortal . trans }.

Subtly different and guaranteed to lock up the system. Why? When we send a message between machines that reference TObjects like the avatar, we don't send the actual object - we send it's name. The target of the message is encoded as well as the arguments. The problem is that this is not done recursively. That is, the actual message that is being sent here is


and its arguments are the message #goToPortal:transform and... an array. We don't do a recursive lookup. That means that we try to send the array and it's contents in toto. Well, in this case, toPortal is a member of the array and is also a TObject that is somewhere inside of a space. It is actually a TPortal, but that doesn't matter. What we are trying to do is package up the TPortal and everything it references and send that. This will fail because we are trying to send the entire contents of the croquet session that probably references all of the Squeak image in some way. Not particularly efficient.

Squeak actually has something that is designed to address this problem that I used in a previous version of Croquet. Unfortunately, I can't find that code exactly, but it is based upon a SmartRefStream, which in turn is a subclass of RefStream, which is simply a way to convert objects to streams and back again. A SmartRefStream is "smart" because it is very aware of multiply referenced objects and can eliminate redundency - very important if you don't want to turn one local object into multiple remote objects. What I did before was added a bit of code that would dereference the objects to their TeaNames if they had one, otherwise it would just encode the actual object.

Once this is in place, then remarkably,

avatar meta future: 0.0 perform: #goToPortal:transform: withArguments: { toPortal . trans }.

will just work.


Monday, October 11, 2004

Jasmine Ships - ReadMe.txt

We just agreed to release Jasmine to the public today. This was a
pretty intense effort. Andreas and I spent two weeks together to port
the new architecture that we did for MadHatter to Jasmine, and then we
seriously upgraded the meta architecture. The last week has been spent
on documentation (still not ready), debugging, and finishing off as
many loose ends as we could. Interesting that the very last thing we
had to do was decide on the name of this release. We all finally agreed
that this is, in fact, Croquet 0.1. This is to ensure that people
understand that this is an early incomplete version of the system. The
"Jasmine" term is the project/release name, so this will change for
every major release that goes out the door.

As always after a release, I am a bit drained rather than exhilarated.
I tend to dwell on the things that are missing and the problems that
are still in the code. Ignorance is bliss - and I just know too much.
Anyway, here is the Read Me from this release (or a close

READ ME - Jasmine 1.0
The Croquet(tm) Developer's Release
The Croquet Committee welcomes you to the Jasmine Developer's Release
of Croquet.

The Croquet Home Page is at Everything related to Croquet is accessible from there, including access to the Croquet system itself.

The Jasmine Developer's Release is intended for people to get their feet wet playing with Croquet. Though most of the system is functional, some key elements are not quite ready and will begin to appear over the next few weeks. This release is really to get you acquainted with the system, deconstruct the examples, and try your own hand at making some things. It is important to note that Croquet is built on top of the Squeak system and includes a complete development environment. In other words, everything you need to develop in Croquet is included as part of this release.

Croquet is an true Open Source project and is covered by an MIT type license. With that in mind, we invite you to participate in the ongoing evolution of the system. You can do this in a number of ways.

First, we have a community mailing list that you should join. You can
do this at:
This is probably the best place to have your questions answered and for you to help others figure out how to extend Croquet.

Second, we have set up a bug tracking system at
You will need to register to use this, but it allows you a place to let us know about any problems that you might have.

Third, you can help by providing us with bug fixes, new features, or just new ideas. Many of the things that we use to demo Croquet came from people who had a neat idea that we just had to implement.

Fourth, let us know what you think. In the end, we are doing this for you. We are truly interested in what you think of what we have done, where it could go, and where we failed. Even if you hate the system, let us know - you could well know something we don't. In the end, we can't make Croquet great without your help.

Launching Croquet
Croquet runs on three different platforms - Macintosh, Windows, and Linux. Each of these have slightly different methods for launching the system. Once you are actually running Croquet, all of the systems work identically. All of the Jasmine folders include essentially the same files. The Jasmine1.0.image and Jasmine1.0.changes are where the actual Croquet system is, but we have made it easy for you by supplying a launch icon.

Macintosh: To start Croquet on the Macintosh, just double click on the "Jasmine" app in the folder.

Windows: To start Croquet on Windows, simply double click the "Jasmine" shortcut that you will find in the Jasmine folder.

Linux: To start Croquet on Linux, simply double click or run the "" file.

Getting Started
When you start Croquet, you will see three small window icons (along with the license). To jump into Croquet, just click on the icon labeled "First Steps". This takes you to another desktop where you can begin to play.

1) Press the 'update code from server' button OFTEN and REGULARLY. This will keep your system up-to-date with the latest developments (you can also update the system through the world menu, 'help...' submenu). It is extremely likely that by the time you read this, the system will have a number of updates available that may directly address potential problems that you might otherwise have. Don't wait.

2) Drag one of the four objects from the catalog to the center of the main window. The standard Croquet demo can be accessed by dragging the 'Teapot' object (be warned that because of the amount of stuff in the demo - it may take some time for it to completely load - this WILL improve dramatically).

From this point, you can just experiment. For information on how to maneuver through the Croquet system, please check out the web site user guide at:

Note to Programmers
Croquet is a component-based architecture that makes it extremely quick and easy for you to create useful collaborative objects. The system has been designed from the ground up to make it simple to create truly shared objects of virtually any sort.

For basic information on how to approach programming in Croquet, please
refer to:

(Please note that this site does not attempt to teach you how to use the Squeak programming environment, or how to program in OpenGL. There are a number of useful resources available for both of these, includingĂ‚  Squeak: Object-Oriented Design with Multimedia Applications by Mark Guzdial, Prentice-Hall, 2000, and the OpenGL Programming Guide by Mason Woo, Jackie Neider, Tom Davis, and Dave Shreiner, Third Edition. Addison-Wesley. 1999). You will also be able
to download the Croquet Manual from:

Bug Reports
We have a bug report server running at Please let us know of any problems - major or minor.

For more information about Croquet and the Jasmine release, the Croquet
FAQ is available at:

Croquet License
Copyright (c) 2002-2004 by Viewpoints Research Institute, Inc. and other individual, corporate, and institutional contributors who have collectively contributed elements of the Croquet(tm) software code to the Croquet Project. Croquet is a trademark of Viewpoints Research Institute, Inc..

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.



Wednesday, October 06, 2004

Croquet Anyone?

Hi all,

Thanks for your patience. The developer's release of Croquet (codenamed
"Jasmine") is undergoing some final Q&A prior to being made available
for download on Monday, October 11 here:

Croquet Project DownLoads

Jasmine will allow you to begin developing components with some level
of comfort that the interfaces will not change significantly between
this and the user release. That said, there are a number if important
pieces still missing, but we are quite comfortable that these will be
available soon and have decided that there is no reason to wait for
them before releasing the system. Please let us know of any problems
you might run into or ideas for improvement that you might have. This
release represents a major turning point in the evolution of Croquet -
from a closed development effort to one that is open and truly takes
advantage of the dynamics and capabilities of the open source
community. Thanks again for your support.

Best regards,


Wednesday, September 29, 2004

Jasmine Status

Andreas and I are working toward a release of "Jasmine" for Saturday. The major difference is that the TeaTime architecture will not be part of it. Why? This is a very good and deep question. The major reason is that Solar works so incredibly well, and everything we have done so far that uses a TeaTime/TeaParty like architecture is surprisingly slow, except for David Reed's version, which isn't quite done. So what we are doing is the following:

Moving Solar to the Squeak 3.6 image. This gives us a better
environment to develop in. Andreas wants to skip 3.7 and move the
system directly to 3.8 when that is available.

Upgrade the OpenGL rendering model. This is a much nicer interface.
Also, the OpenGL object is only passed to the rendering object at
render time, hence there is no need for global updates of it when it
changes. Overall, a big win. This also means that the initialize
methods are greatly simplified and since #initialize is now always
called by default inside of #new, this clean up the code as well.

Keep the current Solar #step model. This is the major difference
between Solar Croquet and Mad Hatter (as far as the component code is

Upgrade the remote object construction. Currently, this does not allow
nested calls to metaConstruct. For that matter, any nested meta is a
bad thing. This change will allow you to call any meta inside of any
other, hopefully without too much trouble. This SHOULD lead to making
the 3D CAD system I built (see below) truly collaborative.

Synchronization of TObjects. This is everything from copying your
avatar over to the remote machine to copying entire spaces. This may be
in a later release, if we can't quite get it done this week.

Multiple TeaParties. This depends upon the synchronization. Currently,
Solar can only deal with a single TeaParty at a time.

Morphic,Linux, Windows, Mac 2D collaboration. This will be done using
the remote frame buffer (RFB) courtesy of Ian Piumerta. The way this
works is you have a single master component that renders the 2D buffer
and ships it over to the slave components on the remote machines.

From a component view there is one MAJOR difference between Jasmine and
Mad Hatter. In Jasmine, the programmer will have to explicitly deal
with synchronization. That is, the system will not automatically ensure
that messages are sent and executed at the right time, for that matter,
it doesn't guarantee that they are sent at all. It is totally up to the
programmer via the meta messaging architecture I did. There are pluses
and minuses to this approach. On the one hand, the programmer has a lot
more control over what is communicated and when between replicants. On
the other, the programmer has to take control of this and must have a
much deeper understanding of the nature of how the object should stay
synchronized. I did a search for "meta" and "metaSend" and was
surprised by how few of these messages actually get sent. But of
course, it isn't the number of them, but their strategic location in
the code. Further, we won't support multiple teaparties to start, but
should have them quite soon.

I am not certain about this, but I believe that components written in
Jasmine will port to Mad Hatter with no changes and will work
essentially identically, however, there are a number of components that
employ a different strategy between these two models. First, there is a
push update model, as employed by the Mars Rover. This is a
master/slave architecture, where the master broadcasts the current
rover state to the slaves. In this case, the master is determined by
whoever interacted with it last. The second is a pull model, not yet
implemented, that could be employed by the flag (a 3D flag waving in
the breeze). The way this would work is the flag would not update
unless it was being rendered. When you first see it, it will send a
message to all of the peers in the teaparty asking for whoever last
touched it and getting that value. There are some other different
approaches to this as well. Also, time synchronization is much less of
a priority in Jasmine. Messages are still time stamped and sorted, but
they are executed immediately. I plan to implement my simple time model
on top of this, which should dramatically improve robustness.

Tuesday, September 28, 2004

Possible Change

Andreas is coming out today to help work on Jasmine. He and I spoke
about a different approach to synchronization that is more along the
lines of the Solar Croquet architecture. Solar uses a key word, called
"meta" that is used to send messages remotely. The programmer is much
more responsible for how an object acts collaboratively.

The previous example of how a window works demonstrates the difference.
In the new Mad Hatter TeaTime model, the entire TeaParty, or container
of all the objects in a shared environment, is really the basis of
collaboration. That is, any message sent via the TeaParty is
replicated. This tends to be much higher order messages like events
(pointerDown, keyDown, etc). This gives the programmer less control,
but it also allows him to not worry about managing the replication of
state. The objects all run lock-step across all of the users - totally

In the Solar model, the object is totally responsible itself for
guaranteeing synchronization. This means that the programmer needs to
determine which key pieces of state need to be shared. When an event
occurs, the object can act on the event and simply share the result, or
the object can in turn send another message that replicates the
computation. The programmer decides. The advantage is that the
programmer can design an object that is quite efficient. The
disadvantage is that the programmer needs to have a very good
understanding of the nature of the communication - what is important
and what is not.

So the question is - do we trust the programmer?

If we do move forward on the Solar/meta approach, we would need to
seriously upgrade the world synchronization capability of the system.
There are two issues, one is replication of construction - new objects,
and the other is replication of world state, replication of existing
objects upon joining a TeaParty. Currently, our model of replication of
construction is pretty bad. I think I have a way to make this work
nicely, though. We have no replication of world state at all - though I
think this too can be handled nicely.

This would mark a major divergence between Jasmine and Mad Hatter. I
think it is a good idea to build Jasmine this way if only to explore
this further.

Sunday, September 26, 2004

Pointer/Avatar/Camera change

Much of this is quite technical and total gibberish to anyone who
doesn't know anything about the architecture of Croquet. As we get
closer to release, I intend to spend some time writing more useful
notes for people interested in developing for the system. For now, I am
just using this forum so that people can keep track of our progress.
Please feel free to comment, or ask questions. I will endeavor to reply
as quickly as I can.


I have modified the system to generate a TPointer inside of the
replicated TAvatar. The way this works is the original TUserCamera
still has it's own, non-replicated, pointer. This is used to determine
which object is being interacted with at render time. Once this object
is determined, when an event is triggered (pointerDown, up, etc) we
send the TSelection object via the replicated TAvatar, as well as the
event itself. It then transfers the TSelection to it's replicated
TPointer and sends the requested event to it.

There are a number of reasons to NOT just put this pointer into the
array of TRays that the TSpace manages.

First, there is a need to traverse portals. The TCamera manages this
nicely, and it makes little sense to do such a complex transform
multiple times, with the additional overhead of querying the target to
determine if it is a portal and acting accordingly. This may change, as
I may want objects to be able to fall through portals that might be on
the ground, but for now, this is not a priority.

Second, the TPointer can only act on objects that are visible to the
camera, hence there is a significant paring of the tree to a small
subset of the objects in the environment that we need to deal with.

The replicated TPointer has it's own replicated TCamera which is a
non-functioning camera. It maintains a number of key values including
the bounds of the users screen, the viewAngle, and the current camera
transform. These are values that are used for some of the actions that
occur in the world such as the TAvatar jumping to a window. The
distance from the window is determined by these two values and could be
different from each user.

There is still a problem with the avatar after it enters a remote space
that is not fixed by this change set, but I think we are closer to
fixing it with this change.

I also moved the TRay tests into a separate teatime based iteration.
This fixes a big problem that we have glossed over. Since the ray tests
were only being performed at render time, if we have different machines
rendering, this could cause divergent behaviors of things that depended
upon these rays, such as the mars rover.

Saturday, September 25, 2004

Interesting problem

David and I are putting the TPointer into the same TeaParty as the
TAvatar. The reason for this is that currently the TPointer is NOT
replicated, hence we are sending far more messages than we should if it
were. Once it is replicated, then the vast majority of its messages
will be sent locally, hence will be quite efficient. This in itself is
a good thing and will be part of both Mad Hatter and Jasmine.

In making this change of putting the TPointer into the same TParty as
the TAvatar, a problem I had ignored until now becomes a bit more
apparent. In Solar, all "selections" of objects occur locally. That is,
when I select a window, or for that matter generate a pointerEnter
message, this only occurs on the local version of the TWindow. Hence,
it is only highlighted locally. In some ways, this simplifies the idea
of selection and manipulation, as only the local guy is involved. Of
course, if any deep changes occur, then the rest of the world needs to
know about this, which is why we did the meta sends.

Of course, Mad Hatter and Jasmine don't work this way. Instead - every
message that is sent to a replicated object is itself replicated among
all of them. This means that when I have a pointerEnter event, this
message is sent to all of the target objects. For a TWindow to work
properly now, it must be aware that multiple users may be able to work
with it, and now IT must manage all of the users state - where before
it needed to manage only whether a single
pointerEnter/pointerOver/pointerLeave and a single

Why is this a problem? We now need to redesign the window (and
virtually all of the other TObjects) to either service all of the
events on a first come/first serve lock-out everyone else until
released, or we need to keep track of all of users currently
interacting with the object. For example, in Solar, if I select a
windows drag area on one machine and you select it on another, this
works nicely because we are just sending updated location information
to each of the windows. We have a nice tug-of-war demonstrating
robustness. With the new model, the only way I can see this working in
this case is whoever gets to the window first controls it completely.
Some events can still be handled properly, like key presses, but most
act over time, like dragging, drawing a line, etc. In the case of the
TWindow, to drag, it keeps track of the camera's normal vector so that
it can drag perpendicular to this. Multiple cameras from different
locations and orientations would make this fail, possibly dramatically.

So what to do?

Some objects would require a lock-out to work properly, usually between
a pointerDown and pointerUp. The pointerEnter and pointerLeave should
NOT require a lock-out because these usually not deep modifications,
but they would require some kind of reference count. That is, we need
to track how many pointerEnter's have occurred and match these with the
pointerLeaves. In the case of the window, we hilite on the first
pointerEnter, and unhilite on the last pointerLeave. No matter what,
this is more complex code.

The lockout may not be that big of a problem as long as everyone knows
that that is the situation. For ICE, what I did was when a lockout
occurred, I hilited the object in red to show that you could not touch
it. This is actually something that can be done locally with something
like the following:

render: ogl

downPointer = ogl camera pointer ifTrue:[
self hilite: go color.]
self hilite: stop color].

render object...

Not pretty, but it was quite effective in ICE from a UI point of view.
A very clear indication of what the state of the object is, which
avoids confusion. The fact is, my perspective on the world IS different
from yours. What I can and can't do IS different from what you can and
can't, and this MUST be made explicit.

The pointerEnter/pointerLeave reference count and the
pointerDown/pointerUp lockout is a pretty simple pattern to implement.
If anyone has a better idea, feel free to let me know.

Friday, September 24, 2004

Unfortunate Formatting

I have been posting to this via email for the most part which has an
unfortunate side effect of adding line breaks in the wrong place. I am
pretty sure that it is because the email program I use - or the one
that receives on the other end, forces line breaks for a certain width
line, and of course the blogger app does as well. There seems to be a
slight mismatch of the algorithms used however. I suspect that the
email uses something like <= x characters, where the blog uses < x. If
the line happens to be exactly x characters long, an extra word wrap
will be forced. I don't expect people to read this, so I am not going
to worry about it - but just in case you were wondering ... there it

Thursday, September 23, 2004

Mad Hatter Fixes

There were two bugs that we found. The first was related to the fact
that the openGL texture ids were being copied to the other machine.
This meant that when the TForm - the object that holds the glID
attempted to render, it assumed that it was a valid number, and since
in fact this texture had never been instanced on this new machine, it
would fail. This was fixed (as well as the problems with TPrimitives)
by adding a fixup on the receiving side to nil out these openGL
reference values. So now the textures are properly visible.

David never actually saw this problem because he was either running
multiple versions of Croquet in the same image - hence a guarantee that
it would use the same OpenGL id, or he ran one machine as a headless
Croquet server - that is, it never actually rendered anything, and the
other rendering, hence the openGL texture id was never even set, so
when it was copied from the server to the rendering machine, the id
value was indeed nil.

The other problem has to do with the fact that the TPointer object, the
thing we use to determine what we are pointing at - is not actually
replicated. This causes some nasty issues because the TPointer queries
virtually every object at render time to determine if it is selected
or not. What we decided to do here was move all of the TRay tests out
of the rendering loop, which is actually a good thing, and move the
TPointer into the same TeaParty as the TAvatar. This leads to one other
slight complexity and that is that the TOverlaySpaces also need a
TPointer and it really can't be the same one as the replicated version,
hence every overlayed TSpace will also have it's own TPointer. The job
of the TUserCamera will be to arbitrate which of these pointers gets
the events that are sent. It is actually a bit simpler this way, though
it took a bit of thought to figure out what to do. The problem is
understanding how TeaTime and TeaParties really work.

A funny thing I found was that TWindow had a reference to a instance
value called pointerXY (which is the x,y location of the 2D cursor on
the screen), which it grabbed from the TPointer on a #pointerDown. This
was actually never used anywhere inside the TWindow, and it was the
only place that the pointerXY was ever asked for from the TPointer. I
can't imagine what I was trying to do with that value, but it is
interesting how this kind of cruft can find it's way into a system.

Fixing Mad Hatter

Today I am visiting with David R to fix up Mad Hatter. David thinks
that these bugs should be quite easy to fix. Hope he is right.

Currently David is working on a modification to the Squeak garbage
collector parameters. What is neat is that the GC actually has these
parameters available to modify. It turns out (according to David) that
these values were set based upon extremely small memory footprints and
relatively slow machines. Since we have significantly more RAM to work
with these days (none of my machines has less than 512 Meg) and good
virtual memory, we can actually perform GCs less often. What David is
doing is modifying a max allocation counter that keeps track of the
number of allocations before a GC based upon the time it takes to
perform a GC with the goal of having it be less than 10 milliseconds.
This is the value that is required to ensure that multimedia
applications, like sound and video, don't have any interrupt. It does
seem to have a good impact on the performance of Croquet.

Tuesday, September 21, 2004

Mad Hatter Progress

I tried out the newly named "Mad Hatter" version of Croquet again
today. This is the name that David R and I have given the TeaTime
version of the system that he has been working on. The good news is
that much of it seems to be working. The transfer of simple worlds
between my PC and Mac seemed to go well. I found a number of problems,
none of which appear to be serious, but show-stoppers for the time
being nonetheless.

- When my avatar entered the remote world the remote machine received
an error in the TStandIn for the avatar. A TStandIn is just a simple
representative of the object that is created as soon as a message is
sent to that non-existent object on the remote machine. The TStandIn is
placed inside of the world and both fields the incoming messages to the
object and begins the process of loading the object from its originator
machine. I would have thought that by definition the TStandIn could not
signal an error because it is supposed to be a universal message
handler. I guess I was wrong about that.
- For fun, I tried running a small world on my Mac and a huge world on
my PC. This failed on the PC somewhere inside of the morphic objects
that are hung inside the world. In fact, I don't think that these
objects are supposed to be sent, so I may have some obsolete code here.
- When I removed the morphs in the world, I got another error. This was
with just a TFlag and a TMyCube. Not much to transfer at all. This may
be a message synchronization problem as the TFlag is constantly sending
future messages to itself.
- The other problem, and one that I am quite a bit more concerned about
is with the speed of data transfer between machines. I do have some
strategies for dealing with this (see below with the imposters) but I
am not quite certain just how much of a problem we have to overcome
until I get the whole thing working.

I will be seeing David tomorrow and already sent him the error report.

I also sent a message to Andreas about the current speed issues with
the TParty object (not to be confused with the TeaParty object - though
of course they will be).

I also received a message from Mark McCahill that he should have a
version of the object caching system done tomorrow. This will be
essential for both Mad Hatter and Jasmine.

Not much I can do on the Mad Hatter front, so back to Jasmine...

Monday, September 20, 2004

Croquet Status

Things are looking up for a release very soon. First, David Reed looks
like he has a real candidate for the developer release. I just spoke
with him and his major concern is that we beat on it a bit before
launching just to make sure there is nothing major. I will be doing
that tonight and through the rest of the week. Also, Andreas just sent
me a change set for his TParty class that should fix the freeze-up I
saw with the previous version.

I am going to Boston tomorrow and will probably have lunch with David
at Mary Chung's (my favorite Chinese restaurant). Also, I will be
spending all of Thursday with him working on Croquet. This week looks
quite promising.

Sunday, September 19, 2004

Croquet: Things to do

Things to do:
Jasmine is a simpler version of the Croquet architecture intended to
act as a stop gap until the TeaTime version is released. It may be
unnecessary, but I think a lot of the ideas in it will be recycled into
the TeaTime version anyway. I worked hard to make it so that both
versions use the same object models, so any changes in one should be
easily replicated in the other.

- Get the TParty architecture to work properly. Currently waiting for Andreas Raab to fix a bug that causes the system to freeze up. The TParty is actually what the E Language people refer to as a VAT . That is, a collection of objects in a computational subworld that you can only have indirect access to. There are a number of very nice things that Andreas did to make this work. First, every Vat has it's own
independent process, which should make it quite easy to add my lightweight TTime model to it. Second, the entire Vat is easily checkpointed, or streamed out, and resurrected.
- When we do a checkpoint of a TParty, we need to replace the external
TParty references with something useful when we ultimately resurrect
the TParty. Currently, there are three kinds of objects that we need
to deal with that exist in external TParties. The first is the TAvatar
- or the representation of the users in the space. These objects are
transient, hence they need to be simply removed upon a checkpoint. The
second are the portals leading to external spaces. We will be replacing
these with an imposter TSpace object inside its own TParty that looks
like the original, but is much lighter weight. Think of it as a 3D
snapshot. The third kind of object are the TForms inside of the
TTextures. These need to be replaced by the TForm thumbnails when we
- The imposter space maintains a reference to the real space on
another machine. Until the imposter is forced to be rendered (or
touched in any way by the user), it begins the process of downloading
the real object space using it's internal reference. Once the real
space is loaded, the imposter space will replace itself with the real
version. The imposter space lives in its own TParty.
- The thumbnails work the same way. They live in their own TParty.
When they are used in any way, either rendered as an object, or used as
a texture on another object, the thumbnails begin the process of
loading the real texture.
- Since textures are static objects, we can cache them in a global
server somewhere. That is, when you construct a space and use a new
texture in that space, this texture can be written to an external
server. When the space that uses this texture is shared, a reference to
the original texture on this server is also shared. When a texture is
downloaded from the server, it is placed both into the space replacing
the thumbnail and onto a local cache on the disk.
- The next big thing is the actual TTime model. This is well described
in a white paper I wrote, which is unpublished. I need to reread it
before posting anywhere, but this will proceed without the rest of the

This is the "real" version of Croquet. It looks like it may see the
light of day before I actually complete Jasmine, which would be
wonderful - though I intend to continue work on Jasmine if only because
it is a simpler model of the system.
- TeaTime requires the same texture caching mechanism as described
above for Jasmine.
- Need to test out a more massive environment to determine the cost of
- Fix up all of the demos. Rework them into the appropriate
Teaparties. Each demo space really needs to be in its own TeaParty.
- Debugging of course.

The current documentation for developing in Croquet is in very poor
state. I need to completely rethink this - though I would like to have
something in the next three or four weeks.

Walkthrough in Croquet

One of the things I have been thinking about is how I might develop a true 3D design tool inside of Croquet. When I wrote Virtus Walkthrough, I had a rather constrained set of capabilities dictated by the 2D user interface paradigm introduced by the Mac and by MacPaint and MacDraw. The goal became that of figuring out how to extend the existing interface to include a realtime 3D space. This was accomplished by having the tools and the design view be all in 2D, which looked very much like MacDraw, and adding a 3D first person view inside of another window. The user would design the space in the 2D view, and explore it in the 3D view. This wasn't bad, but it meant that you always had to jump back and forth between 2D and 3D, which was a pain.

Here is a picture of it:

We started adding some direct manipulation in the 3D world in later versions of the system, in fact, when we developed OpenSpace, the intended successor of WalkThrough, we left out the 2D manipulation and design entireley. This also proved to be suboptimal. When I first described the idea of removing the 2D view entirely, a friend of mine working at Disney Imagineering said that would be a huge mistake. The 2D view acted as a map that we quite easy to understand and work with. This proved to be the case with OpenSpace. Using it as simply a layout animation tool was great for small non-environment based projects, but it didn't really lend itself to world building. Of course, it really didn't have any design tools either, so this might not have been an issue. But with Croquet - everything is 3D. I think that the key idea here is not to abandon the 2D, but figure out a nice way to interleave it with the 3D. That is, the 2D becomes a true working surface that can be viewed either flat or in context with the extruded 3D data set. The first efforts on this were the Wicket demo I built:

I like this a lot, but the big problem is that I don't really have a tool palette to work with here. This is a more subtle problem than you might think, as the palette needs to live somewhere, without cluttering the collaborative design of the model. Further, everything in Croquet is an independent object. This means that any tool developed needs to communicate with the model via it's messages. But I need to be able to extend the capabilities of the tools independently of the capabilities of the model that I am working on. This problem leads to some pretty crufty approaches in the code. I have not seen anything that works the way I would want.

Saturday, September 18, 2004

Croquet Personal Blog - A Start

Hi there. This is just an experiment to see if I can sustain a blog about the Croquet Project - or anything else I feel like writing about. I decided to give this a try because a friend of mine - Takashi Yamamiya has started a blog using blogger and it seemed pretty easy to start up.

The main thrust of this blog will be technical discussions about Croquet. For more information about Croquet, see:
Croquet Project.