Wednesday, 3 February 2016

SNEAK PEEK: PMAC 2.0

In the last month or so in addition to finishing off the changes to my danceball and testing it, I've also been working on updating PMAC to be compatible with the changes in Opensim 0.9.

While I was at it, I've also added some features that I've either already placed in my own custom systems or are preparatory for some other products I have planned for the coming months.

With the number and scope of these changes it seemed significant enough to warrant a full version number increase rather than a subversion one, so when I finish testing (and documenting) it all, the new version will be released as PMAC 2.0. I don't want to give a firm ETA yet but it will very likely be before the end of February or, failing that, in early March.

In the meantime, I thought I'd give you a sneak peek at what's planned (which might also explain why I'm not releasing other stuff at the moment) and also give a "last call" for any other changes/additions/requests that users might have. If they seem useful and feasible (meet the overall design goals of the system and are something I can do and test within the planned-for release period) I'll try to add them.

CHANGES AT A GLANCE

Here are the quick teasers:
  • wrote a new integrated add-on to (optionally) allow variable auto-timed sequences
  • wrote a new integrated set of quite powerful remote control commands that can be called from another script in the PMAC object or even from a script in a remote prim or HUD
  • PMAC2.0 now has support for more than 9 concurrent users/positions with a couple of minor limitations on functionality
  • added a compatibility update for NPCs to allow them to work correctly in Opensim 0.9 parcels with access restrictions while also continuing to fully support them on 0.8.x regions
  • added a new configuration option to have PMAC be "silent"...effectively shutting it up unless it encounters an error (not that it was chatty before, but now it can be made even less so)
  • added a new configuration option to indicate whether it's only the owner who can access the new remote control commands
  • made a few minor tweaks to improve performance or handle corner cases that could produce unexpected results
  • the configuration notecard data is now string-trimmed when read so it won't generate errors if you accidentally include leading/trailing spaces in your notecard
  • all PMAC 1.x add-ons that I know of (including Seth's, Neo's and Aaack's) are now included inside the builder's kit rather than as separate packs

COMPATIBILITY

All existing PMAC 1.x systems are fully compatible with the new PMAC 2.0 core script with absolutely no changes required. You can simply replace the old core script with the new one and you'll be up and running. All changes are transparent and only represent extra options and controls. The system remains fully compatible with Opensim 0.8.x as well as being fully compatible with the changes to Opensim 0.9 (although you will need to manually adjust/edit positions to move a product back and forth between the two).

I have not and will not build in a global z-axis offset modifier to accommodate the sit target differences between Opensim 0.8.x and Opensim 0.9 due to the detrimental impact it would have on both the PMAC system and simulator performance. A system set up under one would need re-positioning of all animations to work properly on the other but is otherwise fully functional. Please don't complain to me about having to adjust positions...I didn't change the code.

Existing Add-On Compatibility:
  • The four public PMAC 1.x add-ons that I have written are 100% compatible with PMAC 2.0.
  • The MLP-to-PMAC converter script by Seth Nygard is 100% compatible with PMAC 2.0.
  • The NC Props add-on by Neo Cortex is 100% compatible with PMAC 2.0
  • The Content Giver add-on by Aaack Aardvark is 100% compatible with PMAC 2.0
If you use any other add-ons that I'm unaware of, or have made custom modifications to your system, you'll need to consult with their scripters to determine compatibility, but most likely there will be no issues. I took considerable care not to break anything in existing systems.

THE CHANGES IN DETAIL...

NEW: Added a new configuration option "silent" which, if set to TRUE, will only say error messages to chat and all other messages (including quit and user control changes) are silent.

The only things beyond this that it will say are "core" ones such as explaining why a user can't sit, can't activate the controls,  important warnings that are only rarely encountered, etc. or to confirm to the owner on lock/unlock menus.

By default this is set to FALSE. Note that when in use and the system is set to owner-only menus, an attempt by another user to activate the menu will be ignored, silently, without explaination if this option is set.

**********

NEW: Added a new integrated "Auto Set Add-on" directly inside PMAC's Core script that is intended primarily for automated systems where PMAC is configured to be in auto mode and users simply sit while PMAC automates a sequence.

This allows you to have the timer used for advancing animations to be variable and defined at a per-animation level in the group's set-up notecard. Typical applications would be:
  • for certain sequenced club items (the new versions of my Dance Table, Dance Chair, and Dance Stage will all use it; as will a special edition of my Dance Pole)
  • for special sets of animations that are created in sequences (there are several dance and sex ones I've seen that are in a multi-aniamtion extended sequence so this would be ideal for them)
  • for automated, sequenced dance-troop performances or stage shows

This new feature was originally design primarily for use with the other major new feature (remote commands) rather than in general purpose items but was useful enough to make it an internally handled feature.

How it works:

When PMAC is in auto mode, it will check the command block of each animation it plays for the command PMAC_SET_AUTO{f} where "f" is any non-zero positive float value. If found, it will set the autotimer to use this value. NOTE: If a subsequent animation doesn't have a value supplied, it will use whatever the previous animation's timer was, not the system's default (since that value was overridden) so if you plan to use this you'll llikely want to set a time value for each animation in the group.

Example: here's a line from a single-user group of dance animations and will set the autotimer for this animation to 57.5 seconds.

    Dance1|PMAC_SET_AUTO{57.5}|sensual_01|<0.0,0.0,0.4521>,<0,0,0,-1>

If PMAC is not in automode the command is ignored.
Using "SYNCH" does NOT reset the timer.

When auto mode is off and you enable it with "Options > Auto > Auto On" PMAC will check to see if the currently playing animation has a PMAC_SET_AUTO value. If it does, this will be used. If not, it will use whatever the current value of autoTimer is. If you use "Options > Auto > and a value" it will begin by setting the timer to the value you selected, ignoring any value defined for it; however any subsequent animation that has a set timer value will then OVERRIDE the value you set manually.

For example, consider a case where the current animation has PMAC_SET_AUTO{10.0} and the next animation in the notecard has PMAC_SET_AUTO{30.0}

If you start with the autotimer currently off....
    - If you use the dialog menu > Options > Auto > Auto On it will engage auto mode and use the current animation's defined 10 second value for the timer. When it adances to the next animation, the timer will update to the 30 second defined value.

    - If you use the dialog menu > Options > Auto > 120 it will engage auto mode with an intiial value of 120 seconds, so the current animation's value of 10 seconds is ignored and 2 minutes later it will advance to the next animation. When it does so, that animation's preset 30-second value will be used and become the new autotimer value until a different time value is encountered.
   
If you start with the autotimer is currently on....
    - If you select the dialog menu > Options > Auto > 120 it will restart the timer with the 120 second value, and then be updated to 30 seconds by the subsequent animation

The general rule of thumb if you're planning to use this in a PMAC system would be to define auto values for all animations in all groups, or at very least all animations in a single group, and keep in mind that auto value is always maintained at "whatever the last one called was" so it can result in unintended behaviour if your user switches to a different group that doesn't have set values. You might even want to simply restrict menu access to the owner and provide instructions. It all depends on your intended application.

For a general system I wouldn't use this. It's really for automated or remote controlled systems.

***********

NEW: Added a new set of remote commands that PMAC will pay attention to if received via llMessageLinked() or by a dataserver event  from osMessageObject().

These functions are intended primarily for scripting of advanced automated systems where the people seated are passive (usually NPCs, or else avatars who haven't accessed the dialog menu control system) and because of the way the system is designed can ONLY WORK when the current value of PMAC's "user" variable is NULL_KEY or it can lead to errors in subsequent use.

To ensure this doesn't happen, the use of any of these functions except for the synch one will force-set user to NULL_KEY so PMAC will ignore any response they give to an open dialog and that person will need to touch the PMAC object again to become the user once more. While this is slightly inconvenient to a user, it's the only way to make these functions work without breaking the system and, as I say, their intended use is for systems with passive occupants.

Another possible application is custom or stripped-down user menu to replace PMAC's normal one -- one where perhaps you give the owner the full menu and then have PMAC ignore anyone else and present them with a separate menu/dialog for far more limited interaction with the system, using these "hooks" as the method for communicating between your menu handling script and PMAC's main script.

Undoubtledly there are countless other possible applications that I haven't thought of yet. This new command set simply further expands the scope of the powerful integrated core tools available to scripters working with the system.

There are two methods for using the new remote commands feature and you can use either or both. There's no preferred method...both are equally fine and don't conflict with one another:
  • From a script in the same object, using:

    llMessageLinked(LINK_ROOT,-1,command,NULL_KEY);

    ...where command is one of the valid commands below (PMAC ignores any link message where the 2nd field isn't -1)
     
  • Or to use a remote controller (a different prim/linkset/HUD/whatever) you can use osMessageObject() to raise a dataserver event which will react to it:

    osMessageObject(target,command);

    ...where target is the UUId of the root prim of the PMAC object and command is one of the valid commands below

PMAC only expects one command per message so if you need to send several you'll have to do them in a sequence, and if the order they're executed is important you'll need to add some sort of delay between them to allow for potential asynchronous message handling in a busy simulator.

The implementation of this also requires a new PMAC configuration setting "ownerOnlyRemote" which allows you to decide whether to only pay attention to a remote, scripted object with the same owner as the PMAC system.

If the PMAC settings option is ownerOnlyRemote=TRUE, on receiving the osMessageObject() call the system will check the owner of the item sending the message and ignore anything that doesn't come from the same owner as the owner of PMAC system. This protects these commands from potential griefers (although you can achieve the same net effect by disallowing others to use that OSSL function or disallow scripts completely).

This check is NOT PERFORMED if ownerOnlyRemote=FALSE so someone could, potentially, intentionally grief a PMAC system but it would also allow you to distribute a HUD or some other device as part of a more elaborate automated PMAC system...you'll have to evaluate the risks and decide for yourself.

Commands and syntax:

PMAC_REMOTE_QUIT
  • This comand is identical to clicking "QUIT" on PMAC's dialog menu which kills any seated NPCs (even ones that PMAC didn't rez) and unsits any avatars. If the unit is set with the option to reset the script on quit, that will occur as well.
  • This command is silently ignored if PMAC is not in "RUNNING" state (in use and not in edit mode)
    PMAC_REMOTE_SYNCH
  • This command is identical to clicking the "SYNCH" button on PMAC's dialog menu
  • This command is the only one that does not set user to NULL_KEY
  • This command is silently ignored if PMAC is not in "RUNNING" state

PMAC_REMOTE_SWAP|p1|p2
  • This command swaps the two specified positions p1 and p2 more or less the way menu-driven swap works
  • The positions are supplied as 2 integers reflecting the animation positions you want to swap, where position 0 is the first one, 1 is the 2nd, etc... (ie like list indices) so, for example, in a 2-person group you would be using the command PMAC_REMOTE_SWAP|0|1
  • The order you supply them in doesn't matter as long as both are valid
  • Just like the menu-based version, a position doesn't need to be occupied in order to be swapped, and a synch is triggered when it happens (even if both are vacant)
  • If either position isn't valid, the swap will be refused with a warning
  • This command is silently ignored if PMAC is not in "RUNNING" state
PMAC_REMOTE_UNSIT|p
  • This command causes PMAC to unsit the occupant of position "p" if it is occupied or fails silently if it is empty or invalid, much like the menu-driven unsit works
  • The position value is supplied as an integer reflecting the position index you want to unsit, where position 0 is the first one, 1 is the 2nd one, etc...(like list indices) so, for example, to have the occupant of the 1st position stand you would use PMAC_REMOTE_UNSIT|0
  • Unlike the menu-based unsit, if the occupant is a NPC it is NOT REMOVED (killed) so you will need to handle its subsequent removal via an external script
  • This command is silently ignored if PMAC is not in "RUNNING" state
PMAC_REMOTE_AUTO_OFF
  • This command is the same as clicking AUTO-OFF on PMAC's dialog menu and disables auto mode if it was active.
  • This command will work when PMAC is in any state.
PMAC_REMOTE_AUTO_ON or PMAC_REMOTE_AUTO_ON|f
  • Turns on auto-play more or less exactly like using the dialog menu to do it
  • If you include a pipe symbol followed by a float >0.0 the supplied value will be used for the timer (example to turn it on and set the timer to 30 seconds, you would send the command "PMAC_AUTO_ON|30.0").
  •  If use just send the command "PMAC_AUTO_ON" with no timing value, or if the value you've supplied is invalid, PMAC will check to see if there is a custom timer value for the current animation and use that if it finds one
  • Otherwise it will use whatever the current value of the autoTimer variable is (which is whatever value is most recently had, or its default value if it hasn't been used yet since the last script reset)
  • NOTE: just like doing this from the menu, this simply starts the timer and doesn't restart or synch the current animation. The next animation will begin playing afer the timer elapses and if it has a PMAC_SET_AUTO command it will override any timer value you've set.
  • If PMAC is not in "RUNNING" state this function sets (and remembers) the new auto timer value but doesn't activate it. When someone sits to begin using the system, the timer will begin.
    PMAC_REMOTE_SET_GROUP|groupName
  • This command is the same as selecting a group from dialog menu
  • The "groupName" supplied after the pipe symbol must be valid "trimmed" group name or the command is ignored (with error message to owner)
  • A"trimmed" group name is the name without the prefix...example: you would use "dances" as the groupname for the group notecard ".menu012A dances")
  • NO PERMISSION CHECK is performed against the menu's permission settings to see whether the users are allowed to play that group or not; but if someone touches the unit to assume control of it again (to become "user") it will do so and not show a prohibited group.
  • NO USER COUNT CHECK IS PERFORMED prior to attempting to load the group, so if you currently have more users than the new group allows, it will fail on the loadGroup call and potentially generate a script error warning and/or chat warnings...
  • The intended purpose for this is to allow you to change the group remotely either prior to use or when the system is already in use in auto mode.If the item is in use but in manual mode and you change group and then subsequently enable auto mode, it will begin cycling through animations from the newly loaded group, not the old one (which may be what you want it to do anyway).
  • This command works in all PMAC states so if the unit is not currently in use it will set the new group which will be ready and loaded for the next person who uses it.
   
PMAC_REMOTE_SET_ANIMATION|groupName|animationName
  • This is the same effect as manually selecting a specific animation from the dialog except you need to supply both the "trimmed" group name and the animation name within that group that you want to play. If auto mode is enabled when this message is received, it is disabled and NOT subsequently re-enabled so you may need to follow it with a command to turn auto back on that's what you want.
  • The "groupName" portion of this is exactly as per above and there is no permission check done...the group is loaded (if found) and then the animation check is made
  • The animation name is the one used as the first field in the notecard's line
  • If no animation can be found by that name the command is ignored but PMAC's current group will have changed to the one specified during the call so this could potentially cause serious problems for subsequent operation so the system is placed into error state until it is reset. For this reason the error is said to local chat and quit is triggered as well.
  • If you're using this function, TEST YOUR SET-UP CAREFULLY AND THOROUGHLY to make sure it works before you distribute it. Note that this is only a potentially severe issue if the group exists but the animation name doesn't...if the group is invalid or missing it will simply ignore the command with a minor error warning to the owner but continue to work properly in all other respects.
  • This command works in all states so you can remotely pre-select the first animation that will play when someone first sits down and activates the system

None of the above give any sort of confirmation notices or feedback to the script that calls them but many (all?) will trigger a standard PMAC global link message of one type or another if successful. You can then use that passed data to detect and confirm the intended effect.
   
REMEMBER: using one of these commands sets the current user (if any) to NULL_KEY so if you've made any customizations to PMAC where the "user" variable is important you'll need to adapt it to test for non-null user.

***********

NEW: PMAC 2.0 now PARTIALLY supports as many concurrent users as you want via a small change in way it pulls the number of positions from the menu notecards. Now the format is:

    .menu[ss][n...][p] Groupname

Where:
    - as before, the group notecard name must begin with the string ".menu"
    - this must be followed by exactly 2 characters that are only used for to help you sort the group order
    - NEW!!!! this can now be followed by either a single-digit or 2-digit (or even 3-digit or more!) integer to indicate the number of positions
    - the final character must be either "A" or "G" or "O" to indicate whether the group permission is all, group or owner
    - followed by a space
    - followed by the name of the group (which must be a unique name)

During initialization, PMAC now checks the length of this intial string when building its internal lists so all of the following names would all be valid
    .menu031A Just Me            PMAC reads the number of positions as "1" = 1
    .menu0301A Just Me            PMAC reads the number of positions as "01" = 1
    .menu03001A Just Me            PMAC reads the number of posistions as "001" = 1
    .menu0118A Pile ONLY        PMAC reads the number of positions as "18" = 18 positions!

All of your existing group notecard names are still fully valid and require no changes at all to remain compatible with PMAC 2.0. This simply now permits a system to be configured to handle as many avatars/NPCs as your region can manage.

LIMITATIONS:
The only MAJOR limitation is that if you have more than 11 positions you will not be able to fully use PMAC's native swap or unsit features because their menus are limited to a single page. This means you'd never be able to swap or unsit someone for some of the higher positions. You *CAN* still do this using the external remote commands and an external controller script, but because this is really such a special case it isn't (and won't be) directly from within PMAC's native dialogs. For that many users you will probably need to be using an external controller for that sort of thing anyway.

There are a few additional practicalities of Opensim that still limit the number of positions:
  • The maximum contents of a notecard is 64k so if you had 100 positions per animation you'd be severely limited in the number of different ones you can have in the group
  • The maximum number of agents that a viewer will display before "impostering" is currently 65 and most people have this value set far lower; so it's somewhat impractical to have a huge number of positions
  • The time required to update positions and change animations increases as the number of avatars increases. I have tested it successfully with 20 concurrent avatars/NPCs and they remain in synch in my test region, but this is likely to be less accurate as the numbers increase or if there are a large number of avatars in the region already placing it under stress
  • The memory available to scripts is also limited...the more positions and users that have to be tracked, the closer PMAC will get to this limit (although it's unlikely to actually surpass it until you have far more agents than the region can handle)
  • Editing positions for a huge number of avatars would be something of a nightmare. Handles will be rezzed alternating through the colours you supply for them but, even so, that's a lot of bodies to move around...have fun if you try it!

***********

TWEAK: reformatted large portions of the core script to reduce total character usage since the newly added portions were pushing it very close to the max script character limit. I tried to do it in such a way as to keep it fairly easy for other scripters to read and follow (making it easier to script your own custom mods) so it isn't pruned as much as it could be.***********

***********

TWEAK: When reading the configuration notecard (if any) the variable names and supplied values are string-trimmed to remove leading and trailing spaces so it won't generate errors if you accidentally include one.

***********

TWEAK: Changed handling of the corner case where you are in manual mode, select a different group, then enable auto mode without selecting an animation from the new group. Previously, when the timer triggers it would say a warning to chat and disable auto mode. Now it will play the 1st animation of the newly selected group instead without warnings.

***********

TWEAK: Made a slight modification to the nc_props script by Neo Cortex that goes inside objects that are to be rezzed by his props add-on. The script is disabled if the item is worn (so it won't generate an error message when you wear the builder's kit giver object) and now if an item is rezzed manually to the ground instead of by PMAC it will say a warning to chat instead of generating a script error message due to attempting to send a message to a NULL_KEY object.

The new version of this script is now called "nc_props 1.1.1". You can safely leave the old version of the script in any existing objects and it will work fine...this is just a "tidying up" bit of housekeeping.

***********

TWEAK/COMPATIBILITY FIX: To make PMAC compatible with the changes to Opensim 0.9, NPCs are now rezzed with the creation flag value 8 to allow them to enter parcels where access permissions are restricted. You will still need to ensure that the PMAC object is set to the same group as the allowed group so the NPC is rezzed with the correct group assignment. The actual integer value 8 is used instead of the named constant in order to allow PMAC to remain compatible with Opensim 0.8.x and earlier.

***********

WILL NOT FIX: I will not add any sort of global z-axis offset modifier to accommodate the changes in sit target handling in Opensim 0.9 because it adds a significant number of additional calculation steps per animation call that will impair the performance of the PMAC system and increase its load on the region. Further, in position edit mode the tracking/following system for the handles will behave very slightly differently (there will be an odd offset between handle position and avatar position and rotations might appear to occur on a slightly offset axis) but will still work correctly in terms of storing and later playing back the new positions and rotations. Changing the editing system to correct for this would also involve too many additional calculation steps to be viable without it feeling unresponsive or laggy while you're trying to work with it.

Any system created and configured for Opensim 0.8.x or earlier will continue to work perfectly but will need to have all animation positions redone to alter them for correct positioning under Opensim 0.9.

Similarly, new systems created under Opensim 0.9 will work perfectly there, but will need to have the positions for all animations redone for correct positioning to be used in a region running Opensim 0.8.x.

You could write a custom script to do the position changes automatically for your notecards; or make separate versions of your systems for users of each; or you could appeal to the Opensim developers to revisit the decision to break all existing sit targets. I simply can't justify reducing PMAC's performance or increasing its load on a region to accommodate changes made to core.

PLANNED PRODUCTS

These advances in the PMAC 2.0 system will allow it to work as the core controller for a variety of new products beyond the ones that you'd typically think of, and do so extremely efficiently. Products that I plan to release in the coming months for which PMAC 2.0 will be the core hanlder:
  • A special storytelling/presentation system being developed in conjunction with Nara Malone as a tool for the next Hypergrid Story project. This will leverage all of the new and existing "power tools" in the PMAC core product and several of the add-ons; but be almost invisible to the user. ETA on this is late spring or more likey sometime in the summer of 2016.
  • An updated version of my "Paramour Table Dancer" product with a single automated dance sequence that lasts more than 30 minutes before it loops back to the beginning. ETA April 2016.
  • An updated and greatly expanded version of my "Paramour Chair Dancer" product with several different animations sequences lasting between 5 and 10 minutes each before looping. ETA May 2016.
  • Several other longer term projects that aren't yet sufficiently developed to announce.