User Tools

Site Tools


Ruth HUD Protocols

Ruth Skin and Alpha

The control HUDs for Ruth have two major functions: alpha cuts and texture appliers. A single simple protocol controls these actions.

  • Channel: multiple channels have been used, the actual channel is calculated based on a constant appID as:
    // Calculate a channel number based on appID and owner UUID
    integer keyapp2chan(integer id) {
        return 0x80000000 | ((integer)("0x" + (string)llGetOwner()) ^ id);
  • Messages: The message format is (currently) clear-text in a single string formatted as:

The protocol is versioned separately from the mesh because scripts may be used with multiple versions of the mesh. Protocol versions are simple numbers, incrementing with each change. Anything before these extensions is considered version 1, ie RC2, and RC3.

The channel number itself is not a part of the versioned protocol as it is not part of the message format being passed between objects. We consider the various appID changes to be part of the overall release prior to now, ie RC2 and RC3 had different appIDs.

Version Command Arguments Response Notes
1 ALPHA <target>,<face>,<alpha>
1 TEXTURE head|lower|upper,<texture> In v1 <face> is always ALL_SIDES (-1) and <color> is always <1.0, 1.0, 1.0>
2 ALPHAMODE <target>,<face>,<alpha-mode>,<mask-cutoff> <alpha-mode> value should be the LSL constant values (see LSL wiki; <mask-cutoff> is only meaningful for PRIM_ALPHA_MODE_MASK (2)
2 COLOR <target>,<face>,<color>
2 RESETANIM restarts any default hand animations that may be configured
2 SELECT <target>,<value> Selects choice from an element group
2 STATUS <hud-api-version> STATUS,<api-version>,<part-type>,<attached>,<object-info>,<alpha-status>,<texture-status> Detailed contents of the response TBD
2 TEXTURE <target>,<texture>,<face>,<color> <target> may also be 'head', 'lower', 'upper'


2 COLOR COLOR,fingernails,-1,<1.0,0.4,0.6>
2 TEXTURE TEXTURE,upper,1111-22-333333,2,<1.0,1.0,1.0>
2 SELECT SELECT,feet,midfeet


  • find and get status
  • Query current values from the body
    • body gets the uuid of the HUD in the ENQ message, let the ANS use llRegionSayTo() to reply directly
    • HUD chooses channel number in ENQ
    • reply with specifics or with all?
    • format reply in JSON or CSV?

Sundance's Fingernail Project

  • Messages: The message format is specific and only has one form:
    [<0.4, 0.7, 1.0>][1][50]

    (note, the '[]' chars above are literals, not syntax)

    • natural: 0=colored, 1=natural
    • specular: specularity setting
  • Extension format:

Encoding Alpha State

With 8 faces per link and 2 states per face to track we should be able to track each link in 8 bits. However, we need to also be able to have a delta to apply differences to enable things like stored alpha states for partial updates. One way or another we need to be able to mask out bits to change or to not change.

For example, we have a single link of 8 faces with a current state of 0x0F (00001111) with a 1 bit representing visible and a 0 bit representing invisible (much like the alpha value in LSL). So faces 1-4 are hidden and faces 5-8 are visible.

Our particular bit-o-mesh uses bits 1 and 2 for fingernails, 3 for hands, 4-8 for wrist through shoulder segments. With the above setting only the wrist, hands and nails are visible to accommodate a sleeve that doesn't quite fit the elbow when certain animations are played. The state of the fingernails is independent from the arm visibility because sometimes a separate mesh is used for the nails. When adding that mesh we want to turn off the built-in nails in our mythical one-piece arm without affecting the rest of the settings required by the sleeve. So we want a result of 0xC0 and only know that bits 1 and 2 should be zero. To do this we need to mask either the bits that do not change or the bits that do change. Either approach is valid, it seems logical to me to mark the bits to change as that lets you extract the current state for the same (in this case fingernails) easily enough.

So here's the math:

Using bitwise operators:

final = (current & !mask) | command

It is even possible to extract sub-states from a saved state

Desc Current State Command Mask Final State
Turn off fingernails (bits 1 and 2) 0x0F 0x00 0x03 0x0C
Turn on all arms, do not change fingernails 0x31 0xFC 0x03 0xFD

Page Tools