Guide: Productising your Scripts

As I’ve said in one of my other guides, scripts are pretty instrumental in creating the SL that we all know and love (the good and the bad).  One thing I do like about SL is that the barrier to entry for scripting is quite low.  With so many free or open source scripts around, and a very supportive community, many are tempted to have a go at scripting, who might never consider doing any other programming.  And once you’ve written a few scripts and people start to find them useful, you will probably be tempted to put them up on the marketplace.  Well this guide will hopefully give you a few things to think about to ensure you don’t end up spending all your time supporting your scripts when you could be writing new ones!

One of my favourite software engineering books is still Fred Brooks Jr’s “The Mythical Man Month”.  One of the things I like about it, is that it was first written in 1975, (revised in 1995), but still contains so many good  lessons for software engineering today.   Even in these days of agile development and apps.  I have had many reasons over the years to refer people to the essay “The Tar Pit”.  This essay starts by saying:

“One occasionally reads newspaper accounts of how two programmers in a remodeled garage have built an important program that surpasses the best efforts of large teams. And every programmer is prepared to believe such tales, for he knows that he could build any program much faster than the 1000 statements/year reported for industrial teams.” (The Mythical Man Month, Ch 1 “The Tar Pit”).

Paraphrasing dreadfully, it basically says that when you do something for yourself and use it yourself, it will take a unit of time (an hour, a day, whatever – it doesn’t matter exactly).  This is what he calls a program.  However, if you want to make this a reusable component that someone other than you can use, with a suitably generalised specification, configuration options, documentation, manuals, etc, increase the time by a factor of 3.  This is a program product.  If you want the same program but want to use it as part of a larger system, another factor of 3, to allow for integration, interfaces, etc.

Therefore it follows that if you are defining a reusable component of a larger system, to the level that allows you to consider it a product, then allow for a factor of 3×3 that is 9 times more time than doing something for yourself.

When you are selling a LSL script, this is exactly what you are doing – creating a configurable, generalised, reusable component in someone else’s build.  This guide is all about what takes that extra time for a LSL scripted product.

Finishing your script

You’ve written your script, it works for you.  You might have given it to a few people and found that it works for them.  You might even have some scripts already published online, in the free script libraries or via your own website, but would like this script to earn you some spending money in SL.   So you are thinking it would be something useful to put on the marketplace so that others might find it useful too.

Well there is a major thing to consider right up front.

Once your script is on the marketplace those who purchase it will be customers.  They are no longer other members of the community who might be getting a favour from you having let them have your script.  They will expect it to work, fool-proof instructions on how to use it, to be able to use it the way they want to and even if it only costs less than what you could earn in 2 minutes work IRL, they will expect customer service if it goes wrong.

So with that in mind consider some of the following, which might all have to be done once you’ve finished programming your script, but must be done before it can become a product.

Testing

No matter how much testing you’ve already done, I strongly suspect there is more that could have been done (there always is for my scripts).  Testing is a major time vs effort and “diminishing returns” activity.  You will never be able to prove it has no bugs.  The best you can do is think about different eventualities and trade-off the time it takes to test them all with the level of risk you are prepared to accept.  That will be different depending on the complexity of the script, how much you plan to sell it for and the anticipated take-up.  If you test it to perfection then don’t sell many, you’ve wasted your time.  If you don’t test it, sell loads, but then have to update it it will take a lot of your time to retrofit it.

Selling a cheaper (or free) “beta” version is one option, as long as you make it clear to your customers that they are helping you test it!  Of course, you probably don’t want someone using it in their own products at this point, that would be a significant risk on their part.

Thinking about exactly what to test is a large topic, so I’ve given it a section all of its own (see later).

Permissions

Scripts have to be copy and mod to be editable, so mod on its own makes no sense (if its mod, you can cut-and-paste it out).  So the main issue from a permissions point of view is does someone need to edit your script or not?  And if they do, consider that you are basically making your script full perms.  In general terms then, scripts would typically be:

  • Full perm – i.e. one can edit the script (and therefore copy and paste it out).  Consider adding a license about “fair use” or similar if you don’t want your script ending up as someone else’s product.
  • Copy/Trans – this is what is required if your script is destined for use within someone else’s product.  This allows them to create copies of your script and pass it on to others.
  • Copy – I tend to use this for “personal use” scripts with no other usage limitations (just like “copy only” objects).

Configuration

There are two approaches to configuration – hardcoded in the script or external to the script.  As already mentioned, if you want someone to edit your script to configure it, it will have to be copy/mod at least, which effectively makes it full perm.  Other options for configuration that do not involve editing the script include:

  • At object built time: notecards, prim parameters (e.g. prim name and description) or other inventory contents (e.g. by including landmarks, textures or even other objects if your script rezzes things).
  • At “run time”: by chat, dialog or other prim-to-prim communications (such as link messages)

A quick note about inventory-based configuration (either by notecard or inventory contents).  If you don’t want your users to be manually resetting your script for it to pick up a new configuration every time something changes, then you should catch the changed() event and use it to trigger a script reset as follows:

changed (integer change)
{
   if (change & CHANGED_INVENTORY)
   {
      llResetScript();
   }
}

Needless to say, implementing any kind of configuration system can be a significant amount of effort.  But the effect of not having one might be giving away all permissions to your script.  There are a number of script libraries and sample code showing how to implement configuration systems.

Documentation

Someone once told me that the original programmer for a program should be the last person to let write the documentation for it.  I’m not quite sure what they were worried about, as I don’t know many programmers who would want to :)

However, if you want anyone to be able to use your script and value your own personal time and don’t want to be forever answering questions about your script, it is worth investing some time writing good documentation.  This can be in the form of a notecard or maybe a website (or both).  I often try to think about what is the absolute minimum the user will need to know just to try it out and write that first.  Then almost anything else is “advanced” and can be described as such.  This way your customers can get started with your script more easily.

I try to include a link to my website in the notecard instructions that I provide, so that people have the option to go and see if there are any more detailed, updated or otherwise extra instructions online even some time after they’ve purchased my script.

And like anything else, your documentation, if it is describing how to do something, has to be tested.  Get an alt and follow your own instructions to make sure they work.  Find a friend to proof read it for readability for you.  Find a techie to review it for technical accuracy for you.  Or maybe find someone who has used an early version of your script to check it out for you.

Don’t forget to include any of the more obscure configuration options you might have included.  Also consider how different options might interact with each other.

You’ll also need to document any special assumptions and don’t forget to include installation instructions if required.

It might also be worth trying to anticipate your user’s questions and include an FAQ section.

Testing your script

This is a massive topic, especially with all the quirks of LSL.  I cannot give you a complete guide to testing your scripts, but here are some of the more edgy cases you might not have thought about that might be relevant to you.  How much you test … well that is up to you.  I certainly wouldn’t consider doing all this for every script – I’d never have time for anything else.  As I’ve already mentioned its a balance of time and risk.  All I will say on this front though, is resist those last minute (just as you are about to upload to the marketplace) one-line changes.  Always check them, even if it’s just a review or diff of the code!

First of all, naturally test the core functionality of your script.  What it is designed to do.  Think about the most common configurations and make sure they work ok.  Then start thinking about more unusual configurations and see if they are all ok too.

Any script outputs (e.g. error messages or instructions) should be read for accuracy, speling, grammar, formatting (e.g. multiple lines) and so on.  Do you need other language options?  Also the scope of any outputs should be considered – should they be owner only (check it) or in open chat (said/whisper/shout)?

Once the main script functions as you intend, consider if you need to test any of the following:

  • On rezzing
  • On rezzing, taking into inventory and rezzing again.
  • When owner changes (a common gotcha for listens tied to user UUIDs – see the wiki)
  • In laggy environments
  • If moved across Sim boundaries
  • On region restarts (not quite sure how you test this, but at least think if it is an issue and look for it happening if you need to)
  • If it is meant for a prim, but gets worn as a HUD
  • If it is meant for a HUD but then gets rezzed as a prim

If you have a configuration system, consider some of the following:

  • Expected configuration is not present
  • Configuration is present but has syntax errors or is incomplete – does your script provide sensible defaults?
  • If your script accepts notecards, what if there are several notecards present?
  • Does your script give the user sensible clues if there are configuration problems?
  • If you accept instructions via chat or dialog, there is basically a user-command protocol to be tested here – valid input, invalid input, mischievous input, etc.
  • Who should be able to configure your system and does any access control (e.g. owner only) work properly?

Performance

  • If you are doing things in timers based on user-input (or prim properties) what if the execution time in the timer event exceeds the timer period?
  • If you are working with lists, have you checked free memory for your worse case scenarios, especially if you are passing lots of lists around in functions?
  • If you have lots of strings, again have you checked your memory usage?  Does it allow enough for your script to function ok (especially if left running for any length of time)?
  • Do you have several scripts working together?  They might be using twice as much sim memory – could you get by with a single script?  Sometimes the tradeoff of combining scripts is worth it, sometimes it is not possible as it can’t all be contained in a single script.

Specific LSL things to think about testing for:

  • Dialogs – think about when do they time out, “ignore” behaviour, timing out of listens, recreating of listens, etc.  There are also oddities with proximity of listening objects to the root prim (see the limits section of llDialog on the wiki)
  • Touch – can you cope with several avatars touching at the same time?
  • If using link messages or chat messages include something specific to your script to allow for other scripts sending messages that your script might see.  Specifically do you check the channel in a listen() event, etc?  If you define a communications protocol (e.g. a message) include something unique to your script and check it on reception, etc.  Check your script ignores unrecognised messages.
  • If you are using several scripts in the same prim, what if one script is missing or if scripts have been duplicated?

Don’t forget to test your installation procedure – on a fresh prim and new alt (remember many properties of prims are remembered even with out scripts – e.g. sit targets, etc).  Also remember that start_entry() is not called by default on rez or owner change, so any “first time” behaviour will only trigger with an explicit (user or script generated) reset.

And as already mentioned, don’t forget to test your documentation.

Releasing your script

When the time comes to release your script, it is time to ask yourself the question: “if this script proves popular, how would I update it once a lot of people have it in their inventories?”

This is therefore a good time to think about anything else you might need to do prior to letting it lose on the world.  That includes things like confirming the permissions – are there two versions?  Maybe one for personal use and one for builders use?  Or maybe a real product and a demo product?

What about debug information?  Do you have a debug, with liberally scattered llOwnerSay() statements around, and a released version that is silent?  Which did you test?  So which should you release?

I find it really useful to include:

integer gDebug = FALSE;
doDebug (string msg)
{
   if (gDebug)
   {
      llOwnerSay (msg);
   }
}

Then I can turn debugging on or off by setting gDebug.  The only downside of this is that any strings that you pass to the doDebug function throughout your code will be taking up script memory even if gDebug is FALSE.  There are some environments that will perform script optimisation and remove unused code, but by default the standard LSL environments don’t.

So whilst gDebug is convenient, if you will be needing every ounce of memory from your script, then you might need to consider if you should comment our your doDebug() calls and remove all those strings from your final script.  You won’t suffer, unless you plan to allow your users to dynamically turn on debugging at run-time to help you solve problems.  But even then, if you are helping one of your customers to this extent, then you could give them a test version with the strings back in (and gDebug set to TRUE) to help anyway.

From this point onwards, releasing is really an exercise in (inventory) configuration management.  You might need to consider:

  • Do you maintain a working area for scripts, then a “production area” for things you’ve released?
  • How do you reference versions of scripts – and do you tie this into the version field in the marketplace?
  • Do you include boxed versions of your scripts for purchase in-world?
  • Are there different versions with different permissions?
  • How can you ensure your inventory items for all of these are obviously linked to each other, so you know which debug version matches which inventory version and which marketplace release?
  • Are you backing up your scripts with out-of-world storage?  (I strongly recommend you do).  How do you tie in scripts on your PC with scripts in your inventory?  Where is the master copy – in or out of world?  Will you remember that when you are attempting to do an update for an impatient customer?

Once your entire set of scripts is consistent, with its associated user documentation, consider what any additional product information you’ll need.  This could include:

  • Textures for marketing
  • Demo objects, photos or videos
  • Text for the marketplace and/or website
  • Landmarks to your store
  • Readme notecard with links to your marketplace store and/or website (don’t forget to thank them for purchasing your product in the first place)
  • Details of in-world groups, RSS feeds or other ways to find out about more products from you
  • What you expect from them in terms of keeping up with support, fixes, new versions, etc – will you contact them or do they need to subscribe to something?  And are updates free or will they need to be bought?

Then its time to get your product on the marketplace and shout about it in all the usual places (see one of my other guides for some thoughts on marketing a new business in SL).

Updating your script

Hopefully, if you’ve prepared your release carefully, at this point you’ll be able to sit back and relax and get on with the next cool project.  However there may come a time when you have an update to perform, a tweak for a customer or a bug fix.

There isn’t a lot to say about this other than everything I’ve said so far applies to updates too!  Here are a last couple of thoughts that relate to updating:

  • Do be careful with your versioning.  Make sure test versions are obviously test – especially if giving a customer test versions to try out. Maybe make the permissions more restrictive – someone who doesn’t understand scripting might not realise that whist your quick hack seems to work fine for them, it would be a major mistake for them to base their entire product line on it until its been proven!
  • Think about how the documentation will need updating too.
  • Is the update a minor tweak on an existing product or should you really be considering it a new product in its own right?  If a new product, should the old one still be available via the marketplace, etc?
  • Will existing owners of your script need to be informed?  Do you have sales records that allow you to contact everyone or do you rely on them having subscribed (to a group, rss feed, twitter, etc)?  Did they know that when they purchased your script?

Note that there are ways of automatically updating a script from a central point – but that is an awful lot of effort, probably only worth it for major scripting systems and definitely out of scope for this guide!

Good luck with your products!

Thank you for Reading!

If you’ve found this guide useful, please consider if you’d like to purchase the notecard version from the marketplace, and leave me a review or maybe you’d like to pay with a tweet.

Kimm

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: