CCU Programming Guide

Programming Guide v1.9: July 6, 2014

Congratulations on acquiring or becoming a programmable android or doll featuring the ACS Central Control Unit. This guide will assist you in learning to program your unit. If you have questions not answered here, please let JulieDoll know. We want this guide to be as clear and complete as possible, but we do sometimes overlook things.
Defining Controls and Options
Programming Rules
Defining Shortcut Options
Programming a Unit
Settings reference
Actions reference

Program Modules

A Central Control Unit’s programming is defined by one or more Program Modules. A program module is simply a notecard with a special name and a special format. You can download an android’s program module, edit it, and re-upload it, or you can write a program module from scratch.

Program modules’ names always begin with the letter “p” followed by a two-digit number “00” through “99”, followed by a space, followed by a brief name. The number is called the program module’s *level*. In the event that two programs defined in modules with different levels conflict, the one defined by the module with the higher numbered level takes clear precedence. Example program module names are:

p75 Basic
p91 3Laws
p40 JulieDoll restrictions

Comments in the contents of a program module are denoted by any line beginning with a “#”. Such lines are ignored by the unit. Blank lines are also ignored. The programs that come pre-installed on a new CCU have generous comments to help you understand how you might customize your programs, but they do slow down loading of programs. You may consider deleting them once you no longer need them.

Programs compose the rest of each program module. In general, each program is defined on a single line; however, any line ending with a backslash “” will have the next line joined with it. This can help you to keep the module more readable. There are four types of programs: mode definitions, actions, rules, and settings. The format of these programs will be described below.

Level 99 is special in that a program module at level 99 may not be seen, edited, or added by anyone other than the unit itself. This allows the unit to have certain settings that can never be overridden or changed without the unit’s own consent. (hudwidth, trustedcreators, deny, and hackable are particularly recommended to be set here, as there is no reason to allow even your owner to modify these.)

Note for those who edit their own program modules: It used to be the case that program modules edited directly within the CCU sometimes worked for a time, but then reverted to older versions when the CCU is detached and re-worn. This problem has not been reported in quite some time and may no longer exist, but consider keeping a backup copy of any program modules you edit, for safety. Better yet, edit them in inventory in the first place, then copy (or upload) them to the CCU when they are ready.


Your android’s Central Control Unit offers a number of settings (a list is provided below). A program at any level may provide a value for a setting, but only the value provided by the highest level program module is used. If that value is deleted (for example, if it is unset by the use of a control), then the next highest value is used. Each setting has a default value as documented, which may generally be overridden at any level.

To provide a global value for a setting, you can write a rule like the following in a program module:

set clothingfolders=/Outfits

This line provides a value, “/Outfits”, for the setting called “clothingfolders.” (A slightly different syntax is used to set a value as part of a mode; see below. This is confusing. In Version 2, the syntax will likely be less confusing, but until that happens we will have to live with it as is.)

A list of useful settings is provided later on.

States and Modes

Your android’s Central Control Unit has, at any time, a set of states. A state is like a switch: the Power state may be On or Off; the Language state may be Natural, Stiff, or Unit, and so on. Every control on the unit is represented by a state.

Every android has three built-in controls:

  • power: Main power (0=shutdown/S=standby/1=activate)
  • motion: Motor systems (0=freeze/1=unfreeze)
  • speech: Speech system (0=silence/1=unmute)

In addition, most androids will have additional controls that can be defined by their programming. Any program module can define one or more controls, each of which consists of a set of mutually exclusive options (called modes). These controls then become states.

Programming your android, then, becomes a matter of:

  1. Setting global customization options (with settings, as discussed above)
  2. Defining any controls and options it should have
  3. Programming any actions to be taken when the unit enters a state
  4. Programming the rules the unit is to follow while in a state

We will consider each of these in turn.

Defining Controls and Options

A control is defined by a program beginning with the word “mode”. (Sorry. It’s old terminology, but changing it now would be highly confusing.) Here is an example, which defines a control called “Autonomy” with two possible options: “Obedient” and “Autonomous.” (Note the use of trailing backslashes to split a single program into multiple lines.)

mode Autonomy (\
 ) A

Be careful of the punctuation – all of it is important.

Each mode has a string associated with it, consisting of a number and a vector. The number simply assigns a unique number to each mode within a mode type. They should begin with 1 and continue sequentially. They needn’t be used in order, but don’t skip any. The vector (that’s the three numbers in angle brackets) defines the color of any indicator (such as on an access panel, remote control, or the unit’s own HUD) that shows when the unit is in that mode. See this wiki entry for more information about specifying colors as vectors. You may omit the number and vector; if you do, numbers and colors will be automatically assigned in order. It is recommended that for any given mode type, you specify these values for either all modes or none.

Finally, the last value (“A”) tells the unit which indicator to use to report when the unit is in one of these modes. Do not use the same value for more than one mode type. At this time only the values “A” through “F” name existing indicators; if you use a different value, the setting of this control will not be indicated visually on an access panel or remote control.

New as of Version 1.10: You may add a digit after the indicator to require a login to use the control. It will be visible on the Access Panel and other devices like any other control. However, it will not be possible to change its setting using an Access Panel, or using any other device not logged in at the specified level or higher. For example, the following line in a program module will create a control that can only be changed using a Remote Control or Workbench logged in at level 5 or higher. The unit can also change it from its HUD (if selfuse=1).

mode Shape (Doll=1,<0,1,0>;Robot=2,<0,0,1>) B5

Programming Actions when a Control is Set

Once a control has been defined, you may program actions to be taken when the control is set to any given options. Here is an example of how to do this:

action (autonomy=obedient) say:Confirmed. Obedient mode activated.

This causes the unit, when its Autonomy control is set to the Obedient option, to speak a confirmation message out loud. More generally, an action begins with the word “action”, continues with a condition in parentheses (e.g. “autonomy=obedient”, “motion=0”, etc.), a command followed by a colon, then any parameters the command requires. (The colon is required even if there are no parameters.)

If you want to have the unit perform more than one action in sequence upon entering a new mode, you can write the condition once, then use an ellipsis to indicate that each subsequent line will happen at that same condition, like this:

action (autonomy=obedient)...
 self:You are now in Obedient mode, and must obey any order.
 say:Confirmed. Obedient mode activated.

This causes the unit, when it is put into Obedient mode, to (1) become aware that its mode has been changed, (2) wait three seconds, then (3) speak a confirmation message out loud.

Actions may also include the changing of settings, as in the following example:

action (motion=0) set:title=<0,0,1>|This unit is frozen.
action (motion=1) unset:title

This causes the unit’s title to be set to “This unit is frozen” when the unit is frozen, unless another program module at a higher level has set the title to something different. (In which case the unit will be warned about the conflict. To suppress this warning, use “setnowarn:” instead of “set:”.) When the unit is unfrozen, the title is unset, meaning that a title set at a lower level may become effective again.

See below for a list of other commands that may be used in an action program.

Programming Rules to Follow Based On Controls

Once an option for a control has been defined, you may program rules that the unit must follow for as long as the control is set to that option. Here is an example of how to do this:

rule (autonomy=obedient) You must obey any order you 
 are given, whether you wish to or not.

(Note the use of “” to continue a long line on a second line.)

Interpreting these rules is up to the player, so it would be wise to write your rules in straightforward English (or another language your android’s player understands) and to be as clear and concise as possible. The unit’s HUD will display all rules in effect at the time, one by one, reminding the unit of how it is to behave.

As with actions, rules may also use the ellipsis shortcut:

rule (attitude=polite)...
 You will address all male humans as "sir" and all female humans as "miss".
 You will thank anyone who gives you something you desire.
 You may not say anything unflattering about any human.

You can also use the special mode “any”, which is a shortcut for “power=1”:

rule (any) You will always treat your owner with respect.

Rules are not presented when the unit’s power is off, as it does not move, speak, or think in that state.

Defining Shortcut Controls

A Shortcut is similar to an option, in that it creates a button on the unit’s menus which, when pressed, triggers one or more programmed actions. However, there is no state created as a result. A collection of related Shortcuts is called a Group. Every Shortcut must be a member of exactly one group. Here is an example shortcut definition:

shortcut Commands (Strip;Submit;FollowOwner)action (commands=strip) detachall:/Clothing
action (commands=submit) say:This unit will obey.
action (commands=FollowOwner)...
say:This unit will follow its owner.

Programming a Unit

A unit can modify its own programming by deleting, adding, or editing program modules in its CCU directly, if its CCU is not bolted down. However, a unit can also be programmed by someone else – its owner or another operator. Any Remote Control, or the Installation Workbench at the Hub, will offer the option to download an existing program module, delete existing program modules, or upload new ones. Generally speaking, you must log in to the unit using an appropriate password before you may do this. The password you use must provide access to at least the level of program you wish to work with. If you do not have sufficient access, your attempt will fail until you successfully log in.

Passwords are defined by settings in the unit’s programming. There can be up to 9 passwords:

password9    provides access to levels 00-98
password8                              00-89
password1                              00-19

No password is required to access programs at levels 00-09. However, if a program notecard is created whose name is “p## MINIMUM” (capital letters required), then no program module with a lower level than that card will be read. (The card itself does not have to have any contents, but if it does have programs they will be read.) Thus, creating a “p10 MINIMUM” notecard will prevent any program from being created without a password.

By default, each CCU is sold with a root password – password9 – of “autonomycontrolsystemstech” and a password5 of “ACSPassword”. These can of course be changed.

When a program module is uploaded to a unit, the module is compiled. Every program will be examined by the unit to ensure that it makes sense, can be carried out, and does not conflict with a higher-level program. If there are any problems, you will be informed of them, and the program module will not be installed. You may then correct the problem(s) and re-upload the module.

Settings Reference

The listings below indicate in which program module the setting is set in the program modules that come with a Version 1.8 or later CCU (earlier versions were organized differently). You are free to move any of them to another module, or to set them dynamically based on controls rather than with a constant value.

animbooting: The animation to be used while the unit is booting up. Default = “stand at ease”.

animdeactivate: The animation to be used when the unit is deactivated or placed in standby mode (until someone poses it in a different animation). Default=”ACS Frozen”; set in p75 Basic.

animfrozen: The animation to be used when the unit is frozen (until someone poses it in a different animation). Default=”ACS Shutdown”; set in p75 Basic

animlowpower: (For future use.) The animation to be used when the unit’s power is low. If this setting is left blank, the unit’s usual animation continues. (This setting can be useful when the unit normally runs a very busy animation.) Currently has no default, is not set, and is not used if set.

behaviorfolders: A list of folders in your #RLV folder which contain behavior-related items (like animation overriders and speech limiters). See the separate document “Shapes and Clothes: Best Practices” for more information. Set in p99 ShapesClothes.

clothingfolders: A list of folders in your #RLV folder which contain clothing. See the separate document “Shapes and Clothes: Best Practices” for more information. Set in p99 ShapesClothes.

effectshutdown: A list of special effects that happen when you are in standby. Permitted values are dim (dims your screen, as if it’s always night), blur (obscures your vision), blind (mostly blocks your vision), deaf (prevents hearing all chat), nonames (prevents seeing names of nearby avatars). You may use more than one, separated by commas, or leave it blank. (deaf is not recommended for this setting.)

effectstandby: A list of special effects that happen when you are shut down. Permitted values are dim (dims your screen, as if it’s always night), blur (obscures your vision), blind (mostly blocks your vision), deaf (prevents hearing all chat), nonames (prevents seeing names of nearby avatars). You may use more than one, separated by commas, or leave it blank.

hackable: (For future use.) Setting this to “0” provides out-of-character protection against in-character hacking attempts. By default, in-character hacking attempts are permitted. (They are not documented, however. If you want to hack an ACS android, you’ll have to use in-character methods to figure out how.) This should generally be set in a level 99 program. Set in p99 Unitonly but not currently used as hacking is not yet available.

hudwidth: The width of the CCU in the unit’s HUD. Default is 0.75. If the unit has other HUDs that interfere with seeing the HUD properly, it may wish to reduce this size. (Recommended for setting only by the unit in p99 Unitonly).

lastchance: The number of seconds delay between a user clicking your Silence or Shut Down control and you actually losing the ability to speak. This can give you enough time to say hey wait I– Default=6; set in p99 Unitonly.

limit-*: Each “limit-*” setting defines the lowest level of access required to use a specified set of commands. Set and documented in p95 Access.

lowestprogramlevel: No longer valid beginning with Version 1.9.

motorspeech: Set this to 1 to indicate that this unit’s design requires it to be able to move in order to speak properly. Then when the unit is unable to move, its speech will be garbled. Default=0; set in p97 Hardware.

owners: The text specified by this setting is displayed to the unit in its HUD and reported to the workbench, remote control and other devices upon request. Owners named in this setting do NOT automatically acquire any special privileges at this time, and the text is not required to be in any special format. Default is blank, indicating that the unit is self-owned. Set in p95 Access.

panellabel: Specifies text that will be displayed on the unit’s Access Panel menu (if it has an Access Panel). Documented but not set in p97 Hardware.

panellock: If 1, specifies that if the unit has an Access Panel with a door (e.g. Iris or Lightbox edition), the door will be locked. Whenever someone new tries to open it, the unit will be informed and be able to grant or deny permission. (However, if the door is open, anyone in range can reach in and use the controls inside.)

panelkeys: (New in version 1.10) Specifies by UUID one or more individuals who can automatically open a locked panel door. Separate multiple UUIDs with a comma. When one of these individuals tries to open the panel, the unit will not have the opportunity to deny permission.

password*: Each “password*” setting defines a password that permits access to the specified level: password9, password8, password7, …, password1. password9=autonomycontrolsystemstech; password5=ACSPassword; set in p95 Access. Others not set by default.

selfuse: Defaults to 1. If set to 0, the unit may not open or operate its own access panel, may not connect to its CCU with a remote control or the installation workbench, and may not bolt or unbolt its CCU. It can still charge itself, and use its pose and follow options. If its CCU is also bolted down, this effectively places the unit under the control of others. Default=1; documented in p95 Access.

shapefolders: A list of folders in your #RLV folder which contain alternate shapes (as opposed to clothing). See the separate document “Shapes and Clothes: Best Practices” for more information. Set in p99 ShapesClothes.

title: The title (hovertext) to be displayed over your head (assuming you have the ACS Handle object attached, which you always should – it comes free in the same folder with the CCU, and recent versions of the CCU will alert you if it is missing.). Format is “<r,g,b>|text”. Some states (such as AFK, shut down, and standby) will override any title specified in your programming.

trustedcreators: A list of usernames or UUIDs of avatars. If an item attempts to connect whose creator is not on this list, the connection attempt will fail. This helps prevent an item from pretending to be something it is not, like an updater or workbench. It is *not* infallible – a modifyable device created by a trusted user may still contain a script written by someone untrustworthy – but it is helpful. Set to “brattle” in p99 Unitonly.

Programming Action Reference

The following commands may be used in actions. An example is provided for each. For those commands that say they require RLV, or a particular version of RLV, it is the unit that must be running RLV; the controller does not need to.

Basic commands

– Say a thing
say:This unit will now shut down.

– Whisper a thing
whisper:Mode activated.

– Move/emote
emote:begins moving stiffly.

– Think a thing
self:You now feel like this.

– Play an animation (must be in the CCU’s background prim – dragging it into the root will move it there automatically)

– Pause a specified number of seconds (do not use inside seq:)

– Rename (for speech)

– Turn power off, on, or standby

– Turn motion off (freeze) or on (RLV required for full functionality)

– Turn speech off (mute) or on (RLV required)

– Change mode. Note that here, unlike elsewhere, the control and option name must be specified with the same case with which they were defined. (“mode:personality=robot” will not work.)

– Force mode actions to run even if already in mode (good for attach commands sometimes)

– Run a shortcut (yes, just like a mode):

Travel restrictions

– Sit unit on a nearby object


– Stand unit if it is sitting

Communicating with other toys (v1.1.0 and later)

– Say a message on a channel other than 0:

– Whisper a message on a channel other than 0:


– Set a setting (note the syntax is different in an action than it is to set the setting globally):

– Unset a setting (allowing a lower-level value to apply):

– Change the text that appears before each word when unit’s power level is low enough that it can only speak one word at a time:


Attachment commands

The type of attachment may be ACCESSPANEL, BATTERY, DOLLKEY, or potentially other things in the future.

– Set item’s position and rotation:

You can find out the item’s current position and rotation using the workbench, or simply by editing it if it’s yours. The “0” doesn’t mean anything, but must be there. The rotation must be specified as a quaternion. (Sorry.)

– Uninstall item:

– Bolt/unbolt item (RLV required)

– Open the unit’s Access Panel, if it has one that is closed (added in 1.9):


– Close the unit’s Access Panel, if it has one that can be closed (added in 1.9):


Clothing/Shape commands (RLV required for all)

– Attach contents of RLV folder, without detaching any currently-worn items that may occupy the same attachment points as contents of the new folder (or, with RLV versions older than 2.5.0, duplicates “attach”):

– Attach contents of RLV folder. If folder name begins with “+”, does not detaching any currently-worn items that may occupy the same attachment points as contents of the new folder; otherwise does.

– Attach contents of RLV folder. Currently, if folder name begins with “+”, does not detaching any currently-worn items that may occupy the same attachment points as contents of the new folder; otherwise does. This may change in a future RLV version to always detach conflicting worn items.
attach:Clothing/PurpleSkirt,Clothing/Shoes/Ballet flats

– Attach contents of RLV folder and allsubfolders:

– Detach contents of RLV folder:

– Detach contents of RLV folder and all subfolders

– Prevent/allow detaching contents of RLV folder (requires RLV 2.3 or 1.25):

– Prevent/allow detaching contents of RLV folder (requires RLV 2.3 or 1.25):
and all subfolders:

– Allow detaching all folders currently locked by the CCU:

– Prevent detaching CCU & attachments:

– Allow detaching CCU & attachments:

– Remove CCU and all of its attachments:


– Run multiple actions in sequence (added in 1.9). The advantage of this over putting each action on its own line is that it reduces memory usage and speeding program loading and execution because fewer lines need to be remembered and read. Do NOT include wait: in a seq: command. Choose a character to use as a separator that is not used in any of the commands to be run (“+” is often a good choice but any character may be used):

– Set a named timer for a specified number of seconds; when it expires, run a specified command (added in 1.9):


Note that the following commands CANNOT be used in a timer: wait:, set:, setnowarn:, unset:, and seq:.

– Cancel a previously-set timer:


– Program an action to happen the next time a certain event occurs. (This functionality was added primarily for internal purposes; I’m not sure why you would want to use it in programs.) But if you do, it works like this (added in 1.9):

trigger: (otherstate=othervalue),name,command:parameters

Note that the following commands CANNOT be used in a trigger: wait:, set:, setnowarn:, unset:, and seq:.

– Delete a named trigger


Known Issues

  • Programming memory limits are a combination of the number of distinct controls and options with the number of actions and rules. When a program module is added to the CCU, the entire module is read, but only control and option names and a list of line numbers that go with each option are stored (in -ModeManager). When you change modes, the actual lines needed for that mode are read. Actions are read and executed without being stored; rules do get stored, but only while active. Thus, actions and rules may be as long as desired without increasing the chance of running out of memory; only the number of them counts toward memory limits.
  • If -ModeManager generates a stack/heap collision error, it usually means the amount of programming added to the unit has exceeded SL’s limits. You will need to reduce the amount of programming and reboot. It is expected that this limit is currently reached at somewhere around 200 actions and rules, but many factors go into this so a specific number cannot be given.
  • If you choose to report a stack/heap collision or other error, PLEASE include in your report the name of the script in which the error occurred (this is reported in the error). Otherwise it is virtually impossible to figure out what went wrong. If JulieDoll is online when you report the bug, please do not reset scripts, as JulieDoll may be able to learn more about the cause of the problem by examining your CCU before it is reset.
  • At this time, undefined behavior may result if a unit has two modes, one of whose names is a substring of the other (e.g. “Android” and “Android2”). Please avoid this.
  • You cannot use lockfolder: to lock a bunch of subfolders of a folder, then use unlockallfolder: to unlock them all. unlockallfolder: will only unlock folders locked with lockallfolder:. Unlockalllocked will unlock all folders you’ve locked using the method you used to lock them. (This is due to a quirk of RLV that the developers do not consider a bug.)