Table of Contents

About

The Wizardry and Steamworks poseball system is a new minimalist pose-ball system competing with MPL and incorporating many technologies that have been developed for other projects.

Incorporated Technologies

Memory Management

The restrictive Linden platform offers only 64KB of stack and heap to play with. Furthermore, Linden VWs do not provide a means of data storage - a script may read and process all kinds of data, but it has no medium to write that data to.

To that effect, other pose systems such as MLP, use additional scripts that, through message passing, expand the 64KB store. Some of those systems are also limited in the amount of poses they can store and they are restricted to a reasonable limit.

Our system dynamically loads a set (such as sits, or cuddles) from notecards and releases the memory once the user switches to a different set. One of the incurred penalties is a 1-2 second delay until the data-server event loads the notecard. A limitation is that if a set contains too many poses then we will have the same problem as other poseball systems.

However, a set can be split up into smaller components - for example, we split cuddles into cuddles and kisses.

When it comes to sim lag, the memory used by our poseball system is guaranteed to amount to 64KB when idle - this is absurdly small compared to megabytes of memory stashed by other poseball systems.

Persistent Storage

Related to the previous section, we use the object description to store data. The result is that we are able to save settings persistently and at the same time free the scripts from global variables - this is a majorly clean achievement compared to the nPose system. The compensation is adding functions that take up memory - however we prefer a cleaner implementation.

Hardcode vs Generate

Both the nPose system and the MLP variations support poses up to a certain number of avatars. The limitation is obtained implicitly, because the scripts are not meant to be independent of the number of poseballs.

By contrast, our system can support any number of poseballs, as well as being able to synchronize the start of the animations.

On the other hand MLP and nPose generate menus through somewhat structured notecards where hierarchy is given by the syntax of the notecard. Our system generates the menus dynamically. We hardcode universal buttons such as "swap", "exit" or "settings" which can be edited in the code itself since they do not warrant a separate notecard.

Specification Quirks

Linden's implementation of a garbage collector is broken (at the time of writing, 4th of May 2013). This is observable by loading data into a local variable in an event within a state and then leave the event and the state as well (effectively never using the variable again) - at that point, the allocated memory slice is not live anymore and the garbage collector should mark it. Regrettably, that does not happen.

Because of that, we chose to manually trash some variables - which make the semantics obscure (since the specification does mention a functional garbage collector). On the other hand, that prevents the script from senselessly holding onto memory.

Regarding animations, the community at llStopAnimation advises that "if you must stop a looped animation, playing a single frame non-looped one immediately after stopping it, at low priority, will clear the list" which does not seem to be the case. We have found that pausing the script for a second or less after running llStopAnimation seems to bring the broken API back to its senses. Note that the API itself is broken since llStopAnimation should stop the animation in the first place and that the workaround is wrong as well.

State Machine


\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=2.8cm,
                    semithick]
  \tikzstyle{every state}=[fill=red,draw=none,text=white]
    
  \node[initial,state] (A)                    {$default$};
  \node[state] (B) [above right of=A] {$settings$};
  \node[state] (C) [below right of=A] {$count$};
  \node[state] (D) [right of=C] {$read$};
  \node[state] (E) [right of=D] {$menu$};
  
  \path (A) edge	(B)
        (B) edge [in=90, out=120] (A)
	(A) edge	(C)
        (C) edge        (D)
        (D) edge        (E)
        (E) edge [in=-90, out=-90] node {exit} (A);

\end{tikzpicture}

The state machine is summarised above; the helper states for the settings are omitted for brevity and considered as part of the settings state. The interesting part is that we use the count and read states to read notecards on the fly and then commute into the menu state. This simplifies the code because the final menu state is only responsible for displaying a menu and for triggering the animations on the poseballs. It also adds to the overall cleanliness of the implementation by not using meaningless variables to determine when notecards have been read or not. Debugging is also fairly easy, given that an ill-formatted notecard would not let the automata commute into the menu state.

When the automata commutes out of the menu state, all storage variables are flushed, thereby releasing all the requested memory. The extra count state was added in order to query the dataserver for the number of lines in the notecard and then display the ASCII progress bar in the read state.

Index