<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.secondlife.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Xoren+Raymaker</id>
	<title>Second Life Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.secondlife.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Xoren+Raymaker"/>
	<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/wiki/Special:Contributions/Xoren_Raymaker"/>
	<updated>2026-07-27T23:54:55Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlAsc_%26_llChr&amp;diff=19738</id>
		<title>LlAsc &amp; llChr</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlAsc_%26_llChr&amp;diff=19738"/>
		<updated>2007-05-04T23:35:37Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;i&amp;gt;This article is a feature request&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple script feature. Two added functions: llAsc and llChr. These two will convert between characters from a string and their ascii code. This might be especially useful when using font textures..&lt;br /&gt;
&lt;br /&gt;
llAsc returns the integer value that represents the ascii value of the given character.&lt;br /&gt;
llChr does the opposite, returning the character with the given ascii value.&lt;br /&gt;
&lt;br /&gt;
integer llAsc(string character);&lt;br /&gt;
string llChr(integer asciivalue);&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
See also: [[Feature requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlAsc_%26_llChr&amp;diff=19732</id>
		<title>LlAsc &amp; llChr</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlAsc_%26_llChr&amp;diff=19732"/>
		<updated>2007-05-04T21:08:58Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;i&amp;gt;This article is a feature request&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a simple script feature. Two added functions: llAsc and llChr. These two will convert between characters from a string and their ascii code. This might be especially useful when using font textures..&lt;br /&gt;
&lt;br /&gt;
llAsc returns the integer value that represents the ascii value of the given character.&lt;br /&gt;
llChr does the opposite, returning the character with the given ascii value.&lt;br /&gt;
&lt;br /&gt;
integer llAsc(string character);&lt;br /&gt;
string llChr(integer asciivalue);&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Talk:LlGetChannel&amp;diff=18684</id>
		<title>Talk:LlGetChannel</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Talk:LlGetChannel&amp;diff=18684"/>
		<updated>2007-04-26T21:26:09Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Reasons why this feature request shouldn&#039;t be implemented.&lt;br /&gt;
#Would break existing content.&lt;br /&gt;
#Would require hundreds if not thousands of developer hours to code, debug and maintain.&lt;br /&gt;
#Easily griefable. Just open a channel and lock it.&lt;br /&gt;
#Collsions are rare.&lt;br /&gt;
#*If two objects are communicating on random channels, the probability of a collision is 2&amp;lt;sup&amp;gt;-32&amp;lt;/sup&amp;gt;&lt;br /&gt;
#*Sims lag horribly when you have several thousand [[listen]]s open, being that there are 2&amp;lt;sup&amp;gt;32&amp;lt;/sup&amp;gt; channels, stumbling upon a used channel is rare.&lt;br /&gt;
&lt;br /&gt;
Ways to mitigate collisions&lt;br /&gt;
*Your script can do owner and object name checks to validate who is speaking, allowing for the filtering of collisions.&lt;br /&gt;
*Your script can add a header to the message that gives the listener added information that it can use to filter out collisions.&lt;br /&gt;
*A protocol can be designed to move the channel it&#039;s communicating on when collisions occur.&lt;br /&gt;
&lt;br /&gt;
Since this feature-request would break content and there are already methods for mitigating collisions, I cannot support this feature suggestion. --[[User:Strife Onizuka|Strife Onizuka]] 18:36, 19 April 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
I agree. If it breaks a little existing content, then we might think about implementing it, but if a lot of content would become broken, then it would need to be a very important update. Also the point about griefing you name, is a very good argument.&lt;br /&gt;
&lt;br /&gt;
With this article i was merely trying to put the current method to discussion, as i think it isn&#039;t very intuitive how to use this in a secure way. Of cause one would need to use a header and one could even implement encryption and/or compression. But computers are dumb things that only do what we tell them to. If we know all facets of a computer program, we can predict it&#039;s entire flow. Unless (and here is where i am getting near my point) something unpredictable, or at least hard to predict, comes along. Because these situations would not (or at least should not) be hard to be made predictable, i do not like depending on something that *might* break because some people found a small chance of collision enough to depend on.&lt;br /&gt;
I am a professional computer programmer. If i tell my boss something i made *could* break if another copy is being run on a nearby computer, then i would have something to explain. It might be very well tolerated if we were in a hurry to produce something that would work (mostly), but we on second life are in no hurry, i believe, to make things the way they should be. To think about it and make things right and stable, in stead of something that *might* break, is hard to debug if it breaks and is difficult to maintain in the future.&lt;br /&gt;
&lt;br /&gt;
Also, your solutions do not entirely satisfy me. The two objects in the given example would both have prims of the same name, owner and creator. Indeed, they would have a different key, but how would you tell each one which key to listen to? Of cause there are ways around this as well, and even simple ways by asking the user during initialization phase which key to listen to, but this would make it more difficult to set up, more sensitive to wrong user input and the script would need to have quite some extra code to get this setup done.&lt;br /&gt;
&lt;br /&gt;
So, concluding: yes, you are right in saying it&#039;s not as easy as i perhaps pictured it in the article, but i do think it still deserves (and needs) some thinking over. Although, i admit, it is not a very high priority request. --Xoren Raymaker 26 april, 2007&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Talk:LlGetChannel&amp;diff=18680</id>
		<title>Talk:LlGetChannel</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Talk:LlGetChannel&amp;diff=18680"/>
		<updated>2007-04-26T21:23:25Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Reasons why this feature request shouldn&#039;t be implemented.&lt;br /&gt;
#Would break existing content.&lt;br /&gt;
#Would require hundreds if not thousands of developer hours to code, debug and maintain.&lt;br /&gt;
#Easily griefable. Just open a channel and lock it.&lt;br /&gt;
#Collsions are rare.&lt;br /&gt;
#*If two objects are communicating on random channels, the probability of a collision is 2&amp;lt;sup&amp;gt;-32&amp;lt;/sup&amp;gt;&lt;br /&gt;
#*Sims lag horribly when you have several thousand [[listen]]s open, being that there are 2&amp;lt;sup&amp;gt;32&amp;lt;/sup&amp;gt; channels, stumbling upon a used channel is rare.&lt;br /&gt;
&lt;br /&gt;
Ways to mitigate collisions&lt;br /&gt;
*Your script can do owner and object name checks to validate who is speaking, allowing for the filtering of collisions.&lt;br /&gt;
*Your script can add a header to the message that gives the listener added information that it can use to filter out collisions.&lt;br /&gt;
*A protocol can be designed to move the channel it&#039;s communicating on when collisions occur.&lt;br /&gt;
&lt;br /&gt;
Since this feature-request would break content and there are already methods for mitigating collisions, I cannot support this feature suggestion. --[[User:Strife Onizuka|Strife Onizuka]] 18:36, 19 April 2007 (PDT)&lt;br /&gt;
&lt;br /&gt;
I agree. If it breaks a little existing content, then we might think about implementing it, but if a lot of content would become broken, then it would need to be a very important update. Also the point about griefing you name, is a very good argument.&lt;br /&gt;
&lt;br /&gt;
With this article i was merely trying to put the current method to discussion, as i think it isn&#039;t very intuitive how to use this in a secure way. Of cause one would need to use a header and one could even implement encryption and/or compression. But computers are dumb things that only do what we tell them to. If we know all facets of a computer program, we can predict it&#039;s entire flow. Unless (and here is where i am getting near my point) something unpredictable, or at least hard to predict, comes along. Because these situations would not (or at least should not) be hard to be made predictable, i do not like depending on something that *might* break because some people found a small chance of collision enough to depend on.&lt;br /&gt;
I am a professional computer programmer. If i tell my boss something i made *could* break if another copy is being run on a nearby computer, then i would have something to explain. It might be very well tolerated if we were in a hurry to produce something that would work (mostly), but we on second life are in no hurry, i believe, to make things the way they should be. To think about it and make things right and stable, in stead of something that *might* break, is hard to debug if it breaks and is difficult to maintain in the future.&lt;br /&gt;
&lt;br /&gt;
Also, your solutions do not entirely satisfy me. The two objects in the given example would both have prims of the same name, owner and creator. Indeed, they would have a different key, but how would you tell each one which key to listen to? Of cause there are ways around this as well, and even simple ways by asking the user during initialization phase which key to listen to, but this would make it more difficult to set up, more sensitive to wrong user input and the script would need to have quite some extra code to get this setup done.&lt;br /&gt;
&lt;br /&gt;
So, concluding: yes, you are right in saying it&#039;s not as easy as i perhaps pictured it in the article, but i do think it still deserves (and needs) some thinking over. Although, i admit, it is not a very high priority request. --Xoren Raymaker 26 april, 2007&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlRequestUpgrade&amp;diff=17635</id>
		<title>LlRequestUpgrade</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlRequestUpgrade&amp;diff=17635"/>
		<updated>2007-04-21T10:23:34Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request, not an actually existing function (yet)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
llRequestUpgrade(key objecttypeid, integer currentversion, list params)&lt;br /&gt;
&lt;br /&gt;
This command sends a request for an upgrade.&lt;br /&gt;
&lt;br /&gt;
== Upgrading ==&lt;br /&gt;
Sometimes you don&#039;t want to help everyone who has purchased an item you created with an upgrade of that item. In these cases you might want to build in a feature in the object so that it can replace itself for an upgraded version. This is exactly what this command does. It sends a request to the server for an upgraded version of this object and if an upgrade is available, it destroys itself and it is then replaced with an upgraded version.&lt;br /&gt;
&lt;br /&gt;
However, there are several things that may happen, depending on how the upgrade was made available. For this, there would be a command like [[llPublishUpgradableObject]] which takes a key and object name as parameter. For example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The publishing script ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
key typeid = &amp;quot;18b03c24-809b-2c19-68d9-fac357e98d29&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    llPublishUpgradableObject(typeid, &amp;quot;some_upgradable_object&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  upgrade_request(key requester, integer currentversion, list params)&lt;br /&gt;
  {&lt;br /&gt;
    if (currentversion &amp;lt; 1)&lt;br /&gt;
    {&lt;br /&gt;
      llUpgradeError(Requester, &amp;quot;Sorry, your current version is too old. Cannot migrate the settings of your current version to the new one&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if (currentversion == 1)&lt;br /&gt;
    {&lt;br /&gt;
      llConfirmUpgrade(requester, 100, param);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      llConfirmUpgrade(requester, 0, param);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The requesting object script (old version of the object) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
integer version = 1;&lt;br /&gt;
key mytypeid = &amp;quot;18b03c24-809b-2c19-68d9-fac357e98d29&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    llSetText(&amp;quot;Version 1...&amp;quot;, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    list params;&lt;br /&gt;
    params += &amp;quot;some value to pass to new version of object&amp;quot;;&lt;br /&gt;
    params += &amp;quot;another value to pass to new version of object&amp;quot;;&lt;br /&gt;
    llRequestUpgrade(mytypeid, version, params);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The upgraded object script ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
integer version = 3;&lt;br /&gt;
key mytypeid = &amp;quot;18b03c24-809b-2c19-68d9-fac357e98d29&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    llSetText(&amp;quot;Version 3!&amp;quot;, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    list params;&lt;br /&gt;
    params += &amp;quot;some value to pass to new version of object&amp;quot;;&lt;br /&gt;
    params += &amp;quot;another value to pass to new version of object&amp;quot;;&lt;br /&gt;
    llRequestUpgrade(mytypeid, version, params);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  upgraded(integer oldversion, list params)&lt;br /&gt;
  {&lt;br /&gt;
    if (oldversion == 1)&lt;br /&gt;
    {&lt;br /&gt;
      // Do stuff to migrate settings from version 1...&lt;br /&gt;
    } else {&lt;br /&gt;
      // Do stuff to migrate settings from version 2...&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I think the example should make it clear, except perhaps for the second parameter to the llConfirmUpgrade command. Sometimes you might want to support an update for an object, but don&#039;t want to do it for nothing. It might have been a difficult job to support the upgrade from that version to the new one. For this, there would be a money parameter. If the value to this parameter is greater than 0, the user will receive a dialog, asking if the user wants to pay the amount of linden dollars passed.&lt;br /&gt;
&lt;br /&gt;
== Author ==&lt;br /&gt;
Original author: Xoren Raymaker&lt;br /&gt;
This request might need some tweaking.. I&#039;m interested what you think of it and what your ideas are.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlRequestUpgrade&amp;diff=17634</id>
		<title>LlRequestUpgrade</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlRequestUpgrade&amp;diff=17634"/>
		<updated>2007-04-21T10:22:29Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request, not an actually existing function (yet)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
llRequestUpgrade(key objecttypeid, integer currentversion, list params)&lt;br /&gt;
&lt;br /&gt;
This command sends a request for an upgrade.&lt;br /&gt;
&lt;br /&gt;
== Upgrading ==&lt;br /&gt;
Sometimes you don&#039;t want to help everyone who has purchased an item you created with an upgrade of that item. In these cases you might want to build in a feature in the object so that it can replace itself for an upgraded version. This is exactly what this command does. It sends a request to the server for an upgraded version of this object and if an upgrade is available, it destroys itself and it is then replaced with an upgraded version.&lt;br /&gt;
&lt;br /&gt;
However, there are several things that may happen, depending on how the upgrade was made available. For this, there would be a command like [[llPublishUpgradableObject]] which takes a key and object name as parameter. For example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The publishing script ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
key typeid = &amp;quot;18b03c24-809b-2c19-68d9-fac357e98d29&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    llPublishUpgradableObject(typeid, &amp;quot;some_upgradable_object&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  upgrade_request(key requester, integer currentversion, list params)&lt;br /&gt;
  {&lt;br /&gt;
    if (currentversion &amp;lt; 1)&lt;br /&gt;
    {&lt;br /&gt;
      llUpgradeError(Requester, &amp;quot;Sorry, your current version is too old. Cannot migrate the settings of your current version to the new one&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if (currentversion == 1)&lt;br /&gt;
    {&lt;br /&gt;
      llConfirmUpgrade(requester, 100, param);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      llConfirmUpgrade(requester, 0, param);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The requesting object script (old version of the object) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
integer version = 1;&lt;br /&gt;
key mytypeid = &amp;quot;18b03c24-809b-2c19-68d9-fac357e98d29&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    llSetText(&amp;quot;Version 1...&amp;quot;, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    list params;&lt;br /&gt;
    params += &amp;quot;some value to pass to new version of object&amp;quot;;&lt;br /&gt;
    params += &amp;quot;another value to pass to new version of object&amp;quot;;&lt;br /&gt;
    llRequestUpgrade(mytypeid, version, params);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The upgraded object script ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
integer version = 3;&lt;br /&gt;
key mytypeid = &amp;quot;18b03c24-809b-2c19-68d9-fac357e98d29&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    llSetText(&amp;quot;Version 3!&amp;quot;, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    list params;&lt;br /&gt;
    params += &amp;quot;some value to pass to new version of object&amp;quot;;&lt;br /&gt;
    params += &amp;quot;another value to pass to new version of object&amp;quot;;&lt;br /&gt;
    llRequestUpgrade(mytypeid, version, params);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  upgraded(integer oldversion, list params)&lt;br /&gt;
  {&lt;br /&gt;
    if (oldversion == 1)&lt;br /&gt;
    {&lt;br /&gt;
      // Do stuff to migrate settings from version 1...&lt;br /&gt;
    } else {&lt;br /&gt;
      // Do stuff to migrate settings from version 2...&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I think the example should make it clear, except perhaps for the second parameter to the llConfirmUpgrade command. Sometimes you might want to support an update for an object, but don&#039;t want to do it for nothing. It might have been a difficult job to support the upgrade from that version to the new one. For this, there would be a money parameter. If the value to this parameter is greater than 0, the user will receive a dialog, asking if the user wants to pay the amount of linden dollars passed.&lt;br /&gt;
&lt;br /&gt;
This request might need some tweaking.. I&#039;m interested what you think of it and what your ideas are.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlRequestUpgrade&amp;diff=17633</id>
		<title>LlRequestUpgrade</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlRequestUpgrade&amp;diff=17633"/>
		<updated>2007-04-21T10:21:04Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request, not an actually existing function (yet)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
llRequestUpgrade(key objecttypeid, integer currentversion, list params)&lt;br /&gt;
&lt;br /&gt;
This command sends a request for an upgrade.&lt;br /&gt;
&lt;br /&gt;
== Upgrading ==&lt;br /&gt;
Sometimes you don&#039;t want to help everyone who has purchased an item you created with an upgrade of that item. In these cases you might want to build in a feature in the object so that it can replace itself for an upgraded version. This is exactly what this command does. It sends a request to the server for an upgraded version of this object and if an upgrade is available, it destroys itself and it is then replaced with an upgraded version.&lt;br /&gt;
&lt;br /&gt;
However, there are several things that may happen, depending on how the upgrade was made available. For this, there would be a command like [[llPublishUpgradableObject]] which takes a key and object name as parameter. For example:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The publishing script ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
key typeid = &amp;quot;18b03c24-809b-2c19-68d9-fac357e98d29&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    llPublishUpgradableObject(typeid, &amp;quot;some_upgradable_object&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  upgrade_request(key requester, integer currentversion, list params)&lt;br /&gt;
  {&lt;br /&gt;
    if (currentversion &amp;lt; 1)&lt;br /&gt;
    {&lt;br /&gt;
      llUpgradeError(Requester, &amp;quot;Sorry, your current version is too old. Cannot migrate the settings of your current version to the new one&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if (currentversion == 1)&lt;br /&gt;
    {&lt;br /&gt;
      llConfirmUpgrade(requester, 100, param);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      llConfirmUpgrade(requester, 0, param);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The requesting object script (old version of the object) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
integer version = 1;&lt;br /&gt;
key mytypeid = &amp;quot;18b03c24-809b-2c19-68d9-fac357e98d29&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    llSetText(&amp;quot;Version 1...&amp;quot;, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    list params;&lt;br /&gt;
    params += &amp;quot;some value to pass to new version of object&amp;quot;;&lt;br /&gt;
    params += &amp;quot;another value to pass to new version of object&amp;quot;;&lt;br /&gt;
    llRequestUpgrade(mytypeid, version, params);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== The upgraded object script ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
integer version = 3;&lt;br /&gt;
key mytypeid = &amp;quot;18b03c24-809b-2c19-68d9-fac357e98d29&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    llSetText(&amp;quot;Version 3!&amp;quot;, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    list params;&lt;br /&gt;
    params += &amp;quot;some value to pass to new version of object&amp;quot;;&lt;br /&gt;
    params += &amp;quot;another value to pass to new version of object&amp;quot;;&lt;br /&gt;
    llRequestUpgrade(mytypeid, version, params);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  upgraded(integer oldversion, list params)&lt;br /&gt;
  {&lt;br /&gt;
    if (oldversion == 1)&lt;br /&gt;
    {&lt;br /&gt;
      // Do stuff to migrate settings from version 1...&lt;br /&gt;
    } else {&lt;br /&gt;
      // Do stuff to migrate settings from version 2...&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I think the example should make it clear, except perhaps for the second parameter to the llConfirmUpgrade command. Sometimes you might want to support an update for an object, but don&#039;t want to do it for nothing. It might have been a difficult job to support the upgrade from that version to the new one. For this, there would be a money parameter. If the value to this parameter is greater than 0, the user will receive a dialog, asking if the user wants to pay the amount of linden dollars passed.&lt;br /&gt;
&lt;br /&gt;
This request might need some tweaking.. I&#039;m interested what you think of it and what your ideas are.&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlRequestUpgrade&amp;diff=17632</id>
		<title>LlRequestUpgrade</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlRequestUpgrade&amp;diff=17632"/>
		<updated>2007-04-21T10:20:16Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request, not an actually existing function (yet)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
llRequestUpgrade(key objecttypeid, integer currentversion, list params)&lt;br /&gt;
&lt;br /&gt;
This command sends a request for an upgrade.&lt;br /&gt;
&lt;br /&gt;
== Upgrading ==&lt;br /&gt;
Sometimes you don&#039;t want to help everyone who has purchased an item you created with an upgrade of that item. In these cases you might want to build in a feature in the object so that it can replace itself for an upgraded version. This is exactly what this command does. It sends a request to the server for an upgraded version of this object and if an upgrade is available, it destroys itself and it is then replaced with an upgraded version.&lt;br /&gt;
&lt;br /&gt;
However, there are several things that may happen, depending on how the upgrade was made available. For this, there would be a command like [[llPublishUpgradableObject]] which takes a key and object name as parameter. For example:&lt;br /&gt;
&lt;br /&gt;
# The publishing script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
key typeid = &amp;quot;18b03c24-809b-2c19-68d9-fac357e98d29&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    llPublishUpgradableObject(typeid, &amp;quot;some_upgradable_object&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  upgrade_request(key requester, integer currentversion, list params)&lt;br /&gt;
  {&lt;br /&gt;
    if (currentversion &amp;lt; 1)&lt;br /&gt;
    {&lt;br /&gt;
      llUpgradeError(Requester, &amp;quot;Sorry, your current version is too old. Cannot migrate the settings of your current version to the new one&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if (currentversion == 1)&lt;br /&gt;
    {&lt;br /&gt;
      llConfirmUpgrade(requester, 100, param);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      llConfirmUpgrade(requester, 0, param);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The requesting object script (old version of the object):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
integer version = 1;&lt;br /&gt;
key mytypeid = &amp;quot;18b03c24-809b-2c19-68d9-fac357e98d29&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    llSetText(&amp;quot;Version 1...&amp;quot;, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    list params;&lt;br /&gt;
    params += &amp;quot;some value to pass to new version of object&amp;quot;;&lt;br /&gt;
    params += &amp;quot;another value to pass to new version of object&amp;quot;;&lt;br /&gt;
    llRequestUpgrade(mytypeid, version, params);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# The upgraded object script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
integer version = 3;&lt;br /&gt;
key mytypeid = &amp;quot;18b03c24-809b-2c19-68d9-fac357e98d29&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    llSetText(&amp;quot;Version 3!&amp;quot;, &amp;lt;1,1,1&amp;gt;, 1);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    list params;&lt;br /&gt;
    params += &amp;quot;some value to pass to new version of object&amp;quot;;&lt;br /&gt;
    params += &amp;quot;another value to pass to new version of object&amp;quot;;&lt;br /&gt;
    llRequestUpgrade(mytypeid, version, params);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  upgraded(integer oldversion, list params)&lt;br /&gt;
  {&lt;br /&gt;
    if (oldversion == 1)&lt;br /&gt;
    {&lt;br /&gt;
      // Do stuff to migrate settings from version 1...&lt;br /&gt;
    } else {&lt;br /&gt;
      // Do stuff to migrate settings from version 2...&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I think the example should make it clear, except perhaps for the second parameter to the llConfirmUpgrade command. Sometimes you might want to support an update for an object, but don&#039;t want to do it for nothing. It might have been a difficult job to support the upgrade from that version to the new one. For this, there would be a money parameter. If the value to this parameter is greater than 0, the user will receive a dialog, asking if the user wants to pay the amount of linden dollars passed.&lt;br /&gt;
&lt;br /&gt;
This request might need some tweaking.. I&#039;m interested what you think of it and what your ideas are.&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlRequestUpgrade&amp;diff=17631</id>
		<title>LlRequestUpgrade</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlRequestUpgrade&amp;diff=17631"/>
		<updated>2007-04-21T09:20:07Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: llRequestUpgrade(key target, integer objecttypeid, integer version, string param)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request, not an actually existing function (yet)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This command sends a request for an upgrade.&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlGetChannel&amp;diff=17552</id>
		<title>LlGetChannel</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlGetChannel&amp;diff=17552"/>
		<updated>2007-04-19T17:54:49Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Freedom of speech is a very important thing, both in real life and in second life. In second life, objects can speak. They can speak only to their owner, speak over instant message to any object or they can even [[llWhisper]], [[llSay]] or [[llShout]] to a channel of choice.&lt;br /&gt;
This is where the problem starts to form: With a constantly growing number of objects containing scripts, the number of used channels is climbing fast. The chance that two objects (perhaps two copies of the same thing) use the same channel to communicate is getting bigger and bigger. If such a thing would happen, the chance of undefined behavior of objects would be very realistic. I would consider such undefined behavior to be a bug and i personally see any bug as a way for certain people to bring the grid to it&#039;s knees or do other bad things..&lt;br /&gt;
&lt;br /&gt;
A way to prevent these problems is to limit the choice of channel to use, by enforcing a rule. We could allow every object free use of channels 0-9999. Channels above 9999 would then not be free to choose, but would have to be requested, so the server may ensure that the channel is not used by any other objects in the grid. The way to request such a channel for usage is to use the function llGetChannel() which returns an integer, identifying the channel.&lt;br /&gt;
&lt;br /&gt;
The object that requested a channel, becomes owner of this channel and must decide which objects may or may not communicate on it. Therefor a few other functions would need to be added. Other objects could use a new function like llRequestChannelUsage(integer channel), upon which an event would be fired in the script of the channel owner. This could be perhaps a channel_request(integer channel, key id) event and the owner could then llAllowChannelUsage(integer channel, key id) or llDenyChannelUsage(integer channel, key id). The requesting object would then receive this answer through a new channel_permission(integer channel, bool allowed) event.&lt;br /&gt;
&lt;br /&gt;
This is just an idea and it might still need some thinking over, but i think the idea is clear enough.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See also:&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlGetChannel&amp;diff=17551</id>
		<title>LlGetChannel</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlGetChannel&amp;diff=17551"/>
		<updated>2007-04-19T17:52:25Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Freedom of speech is a very important thing, both in real life and in second life. In second life, objects can speak. They can speak only to their owner, speak over instant message to any object or they can even [[llWhisper]], [[llSay]] or [[llShout]] to a channel of choice.&lt;br /&gt;
This is where the problem starts to form: With a constantly growing number of objects containing scripts, the number of used channels is climbing fast. The chance that two objects (perhaps two copies of the same thing) use the same channel to communicate is getting bigger and bigger. If such a thing would happen, the chance of undefined behavior of objects would be very realistic. I would consider such undefined behavior to be a bug and i personally see any bug as a way for certain people to bring the grid to it&#039;s knees or do other bad things..&lt;br /&gt;
&lt;br /&gt;
A way to prevent these problems is to limit the choice of channel to use, by enforcing a rule. We could allow every object free use of channels 0-9999. Channels above 9999 would then not be free to choose, but would have to be requested, so the server may ensure that the channel is not used by any other objects in the grid. The way to request such a channel for usage is to use the function llGetChannel() which returns an integer, identifying the channel.&lt;br /&gt;
&lt;br /&gt;
The object that requested a channel, becomes owner of this channel and must decide which objects may or may not communicate on it. Therefor a few other functions would need to be added. Other objects could use a new function like llRequestChannelUsage(integer channel), upon which an event would be fired in the script of the channel owner. This could be perhaps a channel_request(integer channel, key id) event and the owner could then llAllowChannelUsage(integer channel, key id) or llDenyChannelUsage(integer channel, key id). The requesting object would then receive this answer through a new channel_permission(integer channel, bool allowed) event.&lt;br /&gt;
&lt;br /&gt;
This is just an idea and it might still need some thinking over.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See also:&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlGetChannel&amp;diff=17550</id>
		<title>LlGetChannel</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlGetChannel&amp;diff=17550"/>
		<updated>2007-04-19T17:50:37Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Freedom of speech is a very important thing, both in real life and in second life. In second life, objects can speak. They can speak only to their owner, speak over instant message to any object or they can even [[llWhisper]], [[llSay]] or [[llShout]] to a channel of choice.&lt;br /&gt;
This is where the problem starts to form: With a constantly growing number of objects containing scripts, the number of used channels is climbing fast. The chance that two objects (perhaps two copies of the same thing) use the same channel to communicate is getting bigger and bigger. If such a thing would happen, the chance of undefined behavior of objects would be very realistic. I would consider such undefined behavior to be a bug and i personally see any bug as a way for certain people to bring the grid to it&#039;s knees or do other bad things..&lt;br /&gt;
&lt;br /&gt;
A way to prevent these problems is to limit the choice of channel to use, by enforcing a of rule. We could allow every object free use of channels 0-9999. Channels above 9999 would then not be free to choose, but would have to be requested, so the server may ensure that the channel is not used by any other objects in the grid. The way to request such a channel for usage is to use the function llGetChannel() which returns an integer, identifying the channel.&lt;br /&gt;
&lt;br /&gt;
The object that requested a channel, becomes owner of this channel and must decide which objects may or may not communicate on it. Therefor a few other functions would need to be added. Other objects could use a new function like llRequestChannelUsage(integer channel), upon which an event would be fired in the script of the channel owner. This could be perhaps a channel_request(integer channel, key id) event and the owner could then llAllowChannelUsage(integer channel, key id) or llDenyChannelUsage(integer channel, key id). The requesting object would then receive this answer through a new channel_permission(integer channel, bool allowed) event.&lt;br /&gt;
&lt;br /&gt;
This is just an idea and it might still need some thinking over.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See also:&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlGetChannel&amp;diff=17549</id>
		<title>LlGetChannel</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlGetChannel&amp;diff=17549"/>
		<updated>2007-04-19T17:50:25Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Freedom of speech is a very important thing, both in real life and in second life. In second life, objects can speak. They can speak only to their owner, speak over instant message to any object or they can even [[llWhisper]], [[llSay]] or [[llShout]] to a channel of choice.&lt;br /&gt;
This is where the problem starts to form: With a constantly growing number of objects containing scripts, the number of used channels is climbing fast. The chance that two objects (perhaps two copies of the same thing) use the same channel to communicate is getting bigger and bigger. If such a thing would happen, the chance of undefined behavior of objects would be very realistic. I would consider such undefined behavior to be a bug and i personally see any bug as a way for certain people to bring the grid to it&#039;s knees or do other bad things..&lt;br /&gt;
&lt;br /&gt;
A way to prevent these problems is to limit the choice of channel to use, by enforcing a of rule. We could allow every object free use of channels 0-9999. Channels above 9999 would then not be free to choose, but would have to be requested, so the server may ensure that the channel is not used by any other objects in the grid. The way to request such a channel for usage is to use the function llGetChannel() which returns an integer, identifying the channel.&lt;br /&gt;
&lt;br /&gt;
The object that requested a channel, becomes owner of this channel and must decide which objects may or may not communicate on it. Therefor a few other functions would need to be added. Other objects could use a new function like llRequestChannelUsage(integer channel), upon which an event would be fired in the script of the channel owner. This could be perhaps a channel_request(integer channel, key id) event and the owner could then llAllowChannelUsage(integer channel, key id) or llDenyChannelUsage(integer channel, key id). The requesting object would then receive this answer through a new channel_permission(integer channel, bool allowed) event.&lt;br /&gt;
&lt;br /&gt;
This is just an idea and it might still need some thinking over.&lt;br /&gt;
&lt;br /&gt;
See also:&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlGetChannel&amp;diff=17548</id>
		<title>LlGetChannel</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlGetChannel&amp;diff=17548"/>
		<updated>2007-04-19T17:49:15Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Freedom of speech is a very important thing, both in real life and in second life. In second life, objects can speak. They can speak only to their owner, speak over instant message to any object or they can even [[llWhisper]], [[llSay]] or [[llShout]] to a channel of choice.&lt;br /&gt;
This is where the problem starts to form: With a constantly growing number of objects containing scripts, the number of used channels is climbing fast. The chance that two objects (perhaps two copies of the same thing) use the same channel to communicate is getting bigger and bigger. If such a thing would happen, the chance of undefined behavior of objects would be very realistic. I would consider such undefined behavior to be a bug and i personally see any bug as a way for certain people to bring the grid to it&#039;s knees or do other bad things..&lt;br /&gt;
&lt;br /&gt;
A way to prevent these problems is to limit the choice of channel to use, by enforcing a of rule. We could allow every object free use of channels 0-9999. Channels above 9999 would then not be free to choose, but would have to be requested, so the server may ensure that the channel is not used by any other objects in the grid. The way to request such a channel for usage is to use the function llGetChannel() which returns an integer, identifying the channel.&lt;br /&gt;
&lt;br /&gt;
The object that requested a channel, becomes owner of this channel and must decide which objects may or may not communicate on it. Therefor a few other functions would need to be added. Other objects could use a new function like llRequestChannelUsage(integer channel), upon which an event would be fired in the script of the channel owner. This could be perhaps a channel_request(integer channel, key id) event and the owner could then llAllowChannelUsage(integer channel, key id) or llDenyChannelUsage(integer channel, key id). The requesting object would then receive this answer through a new channel_permission(integer channel, bool allowed) event.&lt;br /&gt;
&lt;br /&gt;
This is just an idea and it might still need some thinking over.&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Object_Oriented_LSL&amp;diff=17547</id>
		<title>Object Oriented LSL</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Object_Oriented_LSL&amp;diff=17547"/>
		<updated>2007-04-19T16:53:44Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This should be straight forward: Classes in LSL.&lt;br /&gt;
&lt;br /&gt;
Because it might not be clear why this is needed or how this would fit into currently existing LSL, I will try to make this clear through an example.&lt;br /&gt;
&lt;br /&gt;
To keep it simple, this object has two prims, one base and one prim simulating the laser light. The laser light prim contains two scripts and the base prim contains one script, which uses code, written in the two other scripts.&lt;br /&gt;
&lt;br /&gt;
== Class Declaration ==&lt;br /&gt;
This is the first script, containing the interface of a script library, containing the interface of a class.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type libraryinterface;&lt;br /&gt;
&lt;br /&gt;
!exports class Laser;&lt;br /&gt;
&lt;br /&gt;
class Laser: inherits llcConePrim&lt;br /&gt;
{&lt;br /&gt;
  protected&lt;br /&gt;
    function SetPosition(vector pos); override;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create(); override;&lt;br /&gt;
    destructor Destroy(); override;&lt;br /&gt;
&lt;br /&gt;
    function SwitchOn();&lt;br /&gt;
    function SwitchOff();&lt;br /&gt;
&lt;br /&gt;
    function SetColor(colorandalpha rgba); override;&lt;br /&gt;
    function GetColor(): colorandalpha; override;&lt;br /&gt;
&lt;br /&gt;
    property Color: colorandalpha; read GetColor write SetColor;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script introduces a few things yet unknown in LSL, none of which are (at the time of writing) documented feature requests. First line in this script specifies that this script is of a different type than a normal script. It is in fact the interface of a script library. It knows a counterpart called a libraryimplementation, which we will find in the second script. This is done because someone who wants to use the script library, needs to know it&#039;s interface, so these interface scripts need to be viewable by other users, but you might want to protect the implementation part of the library, so hence two scripts are needed, so that one can be viewable and the other not viewable.&lt;br /&gt;
The next line we find, contains an !exports keyword, which says &amp;quot;this script exports something that should be able to be used by other scripts&amp;quot;. In this case, it exports the class &amp;quot;Laser&amp;quot;, which is defined after this.&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; The keywords !type and !exports are both prefixed by an exclamation mark (!) because they tell something about the script itself. They could be seen as extra (optional) properties to a script.&lt;br /&gt;
&amp;lt;b&amp;gt;Note2:&amp;lt;/b&amp;gt; I will not explain in depth here what everything means, i will assume therefor that the general concept and terminology of classes is known.&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Class ===&lt;br /&gt;
Now the actual subject of this feature request. The next line after the !exports keyword begins the definition of a class called &amp;quot;Laser&amp;quot;. Straight into it, we also specify that it inherits from llcConePrim, which would be the base class representing all cone shaped prims. The llcConePrim itself then inherits from the basic llcPrim which would be the base class for all prims.&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Protected ===&lt;br /&gt;
Inside the class declaration, we find the keyword protected. This specifies that things defined after this keyword not available for use by all other code. Only members of the class itself, classes which inherit from this Laser class and classes which are &amp;quot;friends&amp;quot; of this Laser class, can &amp;quot;see&amp;quot; (and therefor use) the protected members declared.&lt;br /&gt;
&lt;br /&gt;
=== The Member Function ===&lt;br /&gt;
A class would be worth almost nothing if it didn&#039;t have member functions. Not much is to be said about these. The keyword &amp;quot;override&amp;quot; that follows it&#039;s declaration means &amp;quot;this functions overrides the functionality of a memberfunction with the same name in the base class&amp;quot;. Of cause this overriding can only be done if the function with this same name was defined as virtual in any of the ancestors. Besides override, there are many keywords to be invented here for use, like &amp;quot;reintroduce&amp;quot;, &amp;quot;abstract&amp;quot;, &amp;quot;overload&amp;quot;, etc.. I think that the idea of &amp;quot;abstract&amp;quot; (pure virtual) and &amp;quot;overload&amp;quot; is clear to most people.&lt;br /&gt;
The keyword &amp;quot;reintroduce&amp;quot; hides any functions of the same name from the inherited classes. Lets say a class A contains a virtual function &amp;quot;Test&amp;quot; with a parameter name as a string and a class B inherits from A and also implements the function Test, but does not have any parameters. You would then use the keyword reintroduce on the function B.Test, because this one reintroduces this functionality and you would not want a user of the class to use A.Test(...)&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Public ===&lt;br /&gt;
After the protected SetPosition member function we find the keyword public. This specifies that functions and such specified after this keyword are publicly available. In other words: every bit of code can &amp;quot;see&amp;quot; the things declared after the keyword public.&lt;br /&gt;
&lt;br /&gt;
=== Constructor and Destructor ===&lt;br /&gt;
The constructor and destructor are special memberfunctions. Every class has a constructor and destructor, but not every class needs to do anything special inside the constructor or destructor. The constructor and destructor are guaranteed to be called when an object of this class is created or destroyed. This way the object can do some initialization and finalization.&lt;br /&gt;
&lt;br /&gt;
=== Class Properties ===&lt;br /&gt;
Near to the end, we find a line defining a so called property with the name &amp;quot;Color&amp;quot;. This works almost like a variable and we will demonstrate this later. When we set the value of this property, the function SetColor will be used and when we will read out the value of the property, the function GetColor will be used to return the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Class implementation ==&lt;br /&gt;
Here is the second script, which contains the implementation of the class defined in the previous section.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type libraryimplementation;&lt;br /&gt;
&lt;br /&gt;
!implements class Laser;&lt;br /&gt;
&lt;br /&gt;
class Laser: inherits llcCubePrim&lt;br /&gt;
{&lt;br /&gt;
  private&lt;br /&gt;
    colorandalpha _Color;&lt;br /&gt;
    bool _State;&lt;br /&gt;
    key _id;&lt;br /&gt;
  protected&lt;br /&gt;
    function SetPosition(vector pos)&lt;br /&gt;
    {&lt;br /&gt;
      llSetPos(pos);&lt;br /&gt;
    }&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create()&lt;br /&gt;
    {&lt;br /&gt;
      _id = llGetKey();&lt;br /&gt;
      _State = false;&lt;br /&gt;
      _Color = &amp;lt;0,0,0,0&amp;gt;;&lt;br /&gt;
      llPrimHide();&lt;br /&gt;
      llTargetOmega(&amp;lt;0,0,0&amp;gt;, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
    destructor Destroy()&lt;br /&gt;
    {&lt;br /&gt;
      // Nothing to do..&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SwitchOn()&lt;br /&gt;
    {&lt;br /&gt;
      _State = true;&lt;br /&gt;
      llPrimShow();&lt;br /&gt;
      llTargetOmega(&amp;lt;1,0,0&amp;gt;, PI, 1);&lt;br /&gt;
    }&lt;br /&gt;
    function SwitchOff()&lt;br /&gt;
    {&lt;br /&gt;
      _State = false;&lt;br /&gt;
      llPrimHide();&lt;br /&gt;
      llTargetOmega(&amp;lt;0,0,0&amp;gt;, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SetColor(colorandalpha rgba)&lt;br /&gt;
    {&lt;br /&gt;
      _Color = rgba;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function GetColor(): colorandalpha&lt;br /&gt;
    {&lt;br /&gt;
      return _Color;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I&#039;ve use a few functions here that might not be actually existing functions, but for the sake of the simplicity of the example.. I don&#039;t know all functions yet, so i couldn&#039;t find a function for hiding and showing the prim the script is part of.&lt;br /&gt;
This shouls be pretty self explanatory, except at the beginning, we see the keyword !implements. This new keyword tells the scripting environment that this script implements the Laser class.&lt;br /&gt;
Further down this script, some people might wonder why the property Color was not present here. This is because properties are interface only. Think about it: What it there to implement on a property? A property only specifies how to read and (optionally) write the value.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
Now perhaps the most important part: How are we to use these classes? Well, remember the !exports keyword, which said that the class Laser was exported? We will now use that exported class in the base object.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type normal; // not needed, but one may specify if one wants to waste time of specifying this that are already default.. ;)&lt;br /&gt;
&lt;br /&gt;
!include LaserCone.LibraryInterfaceScript;&lt;br /&gt;
!include LaserCone.LibraryImplementationScript;&lt;br /&gt;
&lt;br /&gt;
Laser cone1, cone2;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1 = Laser.Create();&lt;br /&gt;
    cone1.Color = &amp;lt;0,1,0,1&amp;gt;;&lt;br /&gt;
    cone2 = Laser.Create();&lt;br /&gt;
    cone2.Color = &amp;lt;1,0,0,1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    state off;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state off&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1.SwitchOff();&lt;br /&gt;
    cone2.SwitchOff();&lt;br /&gt;
  }&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    state on;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state on&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1.SwitchOn();&lt;br /&gt;
    cone2.SwitchOn();&lt;br /&gt;
    llSetTimerEvent(1);&lt;br /&gt;
  }&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    llSetTimerEvent(0);&lt;br /&gt;
    state off;&lt;br /&gt;
  }&lt;br /&gt;
  timer()&lt;br /&gt;
  {&lt;br /&gt;
    float r = llFrand(1);&lt;br /&gt;
    float g = llFrand(1);&lt;br /&gt;
    float b = llFrand(1);&lt;br /&gt;
    cone1.Color = &amp;lt;r,g,b,1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    float r = llFrand(1);&lt;br /&gt;
    float g = llFrand(1);&lt;br /&gt;
    float b = llFrand(1);&lt;br /&gt;
    cone2.Color = &amp;lt;r,g,b,1&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Well, most of this should be a piece of cake, really, except, perhaps, the lines containing the !include keyword. This keyword specifies that this this script would like to use code in a different script. In this case, I immediately went a step further than the basics, including a script which is not part of the content of the same prim, but which is inside a different prim. The prim which contains the scripts in this example is called &amp;quot;LaserCone&amp;quot; and the two scripts are called LibraryInterfaceScript and LibraryImplementationScript.&lt;br /&gt;
Any script from any prim in the set may be included, but only things that are actually exported can be used. In this case, the implementation script does not export anything. It only implements the interface of the Laser class. The interface script does export something: the Laser class, so the last script may use it.&lt;br /&gt;
&lt;br /&gt;
In the state_entry() of the default state, we see two Laser objects are created, stored in the variables cone1 and cone2. Also their Color is set. Pure green for cone1 and pure red for cone2. The way the color is specified here is not currently possible in LSL, but i like to think about color as a 4D vector, including red, green, blue and alpha values, which makes it easier to specify color. Also, OpenGL accepts color this way through glColor4f(r, g, b, a), so it might be better, performance wise, to do it like this. Here, i mostly used it for the sake of the example. It also makes the example class a lot tighter than including a seperate alpha property and set and get methods.&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; From this script, it is impossible to call the SetPosition function, defined in the interface of the class. This is not possible, because this function is defined in a protected visibility and this code is not part of a decendantclass, friend class, or other such code that should be able to see protected functions of the Laser class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Authors ==&lt;br /&gt;
Original author: Xoren Raymaker, April 18, 2007.&amp;lt;br&amp;gt;&lt;br /&gt;
I realize this might need some tweaking, but i&#039;m interested what your ideas and comments are about this idea of mine. It is a big thing to add to SL, but i think it could (in time) greatly enhance flexibility and features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Related ideas ==&lt;br /&gt;
#[[Operator overloading]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Object_Oriented_LSL&amp;diff=17490</id>
		<title>Object Oriented LSL</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Object_Oriented_LSL&amp;diff=17490"/>
		<updated>2007-04-18T19:22:47Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This should be straight forward: Classes in LSL.&lt;br /&gt;
&lt;br /&gt;
Because it might not be clear why this is needed or how this would fit into currently existing LSL, I will try to make this clear through an example.&lt;br /&gt;
&lt;br /&gt;
To keep it simple, this object has two prims, one base and one prim simulating the laser light. The laser light prim contains two scripts and the base prim contains one script, which uses code, written in the two other scripts.&lt;br /&gt;
&lt;br /&gt;
== Class Declaration ==&lt;br /&gt;
This is the first script, containing the interface of a script library, containing the interface of a class.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type libraryinterface;&lt;br /&gt;
&lt;br /&gt;
!exports class Laser;&lt;br /&gt;
&lt;br /&gt;
class Laser: inherits llcConePrim&lt;br /&gt;
{&lt;br /&gt;
  protected&lt;br /&gt;
    function SetPosition(vector pos); override;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create(); override;&lt;br /&gt;
    destructor Destroy(); override;&lt;br /&gt;
&lt;br /&gt;
    function SwitchOn();&lt;br /&gt;
    function SwitchOff();&lt;br /&gt;
&lt;br /&gt;
    function SetColor(colorandalpha rgba); override;&lt;br /&gt;
    function GetColor(): colorandalpha; override;&lt;br /&gt;
&lt;br /&gt;
    property Color: colorandalpha; read GetColor write SetColor;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script introduces a few things yet unknown in LSL, none of which are (at the time of writing) documented feature requests. First line in this script specifies that this script is of a different type than a normal script. It is in fact the interface of a script library. It knows a counterpart called a libraryimplementation, which we will find in the second script. This is done because someone who wants to use the script library, needs to know it&#039;s interface, so these interface scripts need to be viewable by other users, but you might want to protect the implementation part of the library, so hence two scripts are needed, so that one can be viewable and the other not viewable.&lt;br /&gt;
The next line we find, contains an !exports keyword, which says &amp;quot;this script exports something that should be able to be used by other scripts&amp;quot;. In this case, it exports the class &amp;quot;Laser&amp;quot;, which is defined after this.&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; The keywords !type and !exports are both prefixed by an exclamation mark (!) because they tell something about the script itself. They could be seen as extra (optional) properties to a script.&lt;br /&gt;
&amp;lt;b&amp;gt;Note2:&amp;lt;/b&amp;gt; I will not explain in depth here what everything means, i will assume therefor that the general concept and terminology of classes is known.&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Class ===&lt;br /&gt;
Now the actual subject of this feature request. The next line after the !exports keyword begins the definition of a class called &amp;quot;Laser&amp;quot;. Straight into it, we also specify that it inherits from llcConePrim, which would be the base class representing all cone shaped prims. The llcConePrim itself then inherits from the basic llcPrim which would be the base class for all prims.&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Protected ===&lt;br /&gt;
Inside the class declaration, we find the keyword protected. This specifies that things defined after this keyword not available for use by all other code. Only members of the class itself, classes which inherit from this Laser class and classes which are &amp;quot;friends&amp;quot; of this Laser class, can &amp;quot;see&amp;quot; (and therefor use) the protected members declared.&lt;br /&gt;
&lt;br /&gt;
=== The Member Function ===&lt;br /&gt;
A class would be worth almost nothing if it didn&#039;t have member functions. Not much is to be said about these. The keyword &amp;quot;override&amp;quot; that follows it&#039;s declaration means &amp;quot;this functions overrides the functionality of a memberfunction with the same name in the base class&amp;quot;. Of cause this overriding can only be done if the function with this same name was defined as virtual in any of the ancestors. Besides override, there are many keywords to be invented here for use, like &amp;quot;reintroduce&amp;quot;, &amp;quot;abstract&amp;quot;, &amp;quot;overload&amp;quot;, etc.. I think that the idea of &amp;quot;abstract&amp;quot; (pure virtual) and &amp;quot;overload&amp;quot; is clear to most people.&lt;br /&gt;
The keyword &amp;quot;reintroduce&amp;quot; hides any functions of the same name from the inherited classes. Lets say a class A contains a virtual function &amp;quot;Test&amp;quot; with a parameter name as a string and a class B inherits from A and also implements the function Test, but does not have any parameters. You would then use the keyword reintroduce on the function B.Test, because this one reintroduces this functionality and you would not want a user of the class to use A.Test(...)&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Public ===&lt;br /&gt;
After the protected SetPosition member function we find the keyword public. This specifies that functions and such specified after this keyword are publicly available. In other words: every bit of code can &amp;quot;see&amp;quot; the things declared after the keyword public.&lt;br /&gt;
&lt;br /&gt;
=== Constructor and Destructor ===&lt;br /&gt;
The constructor and destructor are special memberfunctions. Every class has a constructor and destructor, but not every class needs to do anything special inside the constructor or destructor. The constructor and destructor are guaranteed to be called when an object of this class is created or destroyed. This way the object can do some initialization and finalization.&lt;br /&gt;
&lt;br /&gt;
=== Class Properties ===&lt;br /&gt;
Near to the end, we find a line defining a so called property with the name &amp;quot;Color&amp;quot;. This works almost like a variable and we will demonstrate this later. When we set the value of this property, the function SetColor will be used and when we will read out the value of the property, the function GetColor will be used to return the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Class implementation ==&lt;br /&gt;
Here is the second script, which contains the implementation of the class defined in the previous section.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type libraryimplementation;&lt;br /&gt;
&lt;br /&gt;
!implements class Laser;&lt;br /&gt;
&lt;br /&gt;
class Laser: inherits llcCubePrim&lt;br /&gt;
{&lt;br /&gt;
  private&lt;br /&gt;
    colorandalpha _Color;&lt;br /&gt;
    bool _State;&lt;br /&gt;
    key _id;&lt;br /&gt;
  protected&lt;br /&gt;
    function SetPosition(vector pos)&lt;br /&gt;
    {&lt;br /&gt;
      llSetPos(pos);&lt;br /&gt;
    }&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create()&lt;br /&gt;
    {&lt;br /&gt;
      _id = llGetKey();&lt;br /&gt;
      _State = false;&lt;br /&gt;
      _Color = &amp;lt;0,0,0,0&amp;gt;;&lt;br /&gt;
      llPrimHide();&lt;br /&gt;
      llTargetOmega(&amp;lt;0,0,0&amp;gt;, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
    destructor Destroy()&lt;br /&gt;
    {&lt;br /&gt;
      // Nothing to do..&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SwitchOn()&lt;br /&gt;
    {&lt;br /&gt;
      _State = true;&lt;br /&gt;
      llPrimShow();&lt;br /&gt;
      llTargetOmega(&amp;lt;1,0,0&amp;gt;, PI, 1);&lt;br /&gt;
    }&lt;br /&gt;
    function SwitchOff()&lt;br /&gt;
    {&lt;br /&gt;
      _State = false;&lt;br /&gt;
      llPrimHide();&lt;br /&gt;
      llTargetOmega(&amp;lt;0,0,0&amp;gt;, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SetColor(colorandalpha rgba)&lt;br /&gt;
    {&lt;br /&gt;
      _Color = rgba;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function GetColor(): colorandalpha&lt;br /&gt;
    {&lt;br /&gt;
      return _Color;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I&#039;ve use a few functions here that might not be actually existing functions, but for the sake of the simplicity of the example.. I don&#039;t know all functions yet, so i couldn&#039;t find a function for hiding and showing the prim the script is part of.&lt;br /&gt;
This shouls be pretty self explanatory, except at the beginning, we see the keyword !implements. This new keyword tells the scripting environment that this script implements the Laser class.&lt;br /&gt;
Further down this script, some people might wonder why the property Color was not present here. This is because properties are interface only. Think about it: What it there to implement on a property? A property only specifies how to read and (optionally) write the value.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
Now perhaps the most important part: How are we to use these classes? Well, remember the !exports keyword, which said that the class Laser was exported? We will now use that exported class in the base object.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type normal; // not needed, but one may specify if one wants to waste time of specifying this that are already default.. ;)&lt;br /&gt;
&lt;br /&gt;
!include LaserCone.LibraryInterfaceScript;&lt;br /&gt;
!include LaserCone.LibraryImplementationScript;&lt;br /&gt;
&lt;br /&gt;
Laser cone1, cone2;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1 = Laser.Create();&lt;br /&gt;
    cone1.Color = &amp;lt;0,1,0,1&amp;gt;;&lt;br /&gt;
    cone2 = Laser.Create();&lt;br /&gt;
    cone2.Color = &amp;lt;1,0,0,1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    state off;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state off&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1.SwitchOff();&lt;br /&gt;
    cone2.SwitchOff();&lt;br /&gt;
  }&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    state on;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state on&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1.SwitchOn();&lt;br /&gt;
    cone2.SwitchOn();&lt;br /&gt;
    llSetTimerEvent(1);&lt;br /&gt;
  }&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    llSetTimerEvent(0);&lt;br /&gt;
    state off;&lt;br /&gt;
  }&lt;br /&gt;
  timer()&lt;br /&gt;
  {&lt;br /&gt;
    float r = llFrand(1);&lt;br /&gt;
    float g = llFrand(1);&lt;br /&gt;
    float b = llFrand(1);&lt;br /&gt;
    cone1.Color = &amp;lt;r,g,b,1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    float r = llFrand(1);&lt;br /&gt;
    float g = llFrand(1);&lt;br /&gt;
    float b = llFrand(1);&lt;br /&gt;
    cone2.Color = &amp;lt;r,g,b,1&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Well, most of this should be a piece of cake, really, except, perhaps, the lines containing the !include keyword. This keyword specifies that this this script would like to use code in a different script. In this case, I immediately went a step further than the basics, including a script which is not part of the content of the same prim, but which is inside a different prim. The prim which contains the scripts in this example is called &amp;quot;LaserCone&amp;quot; and the two scripts are called LibraryInterfaceScript and LibraryImplementationScript.&lt;br /&gt;
Any script from any prim in the set may be included, but only things that are actually exported can be used. In this case, the implementation script does not export anything. It only implements the interface of the Laser class. The interface script does export something: the Laser class, so the last script may use it.&lt;br /&gt;
&lt;br /&gt;
In the state_entry() of the default state, we see two Laser objects are created, stored in the variables cone1 and cone2. Also their Color is set. Pure green for cone1 and pure red for cone2. The way the color is specified here is not currently possible in LSL, but i like to think about color as a 4D vector, including red, green, blue and alpha values, which makes it easier to specify color. Also, OpenGL accepts color this way through glColor4f(r, g, b, a), so it might be better, performance wise, to do it like this. Here, i mostly used it for the sake of the example. It also makes the example class a lot tighter than including a seperate alpha property and set and get methods.&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; From this script, it is impossible to call the SetPosition function, defined in the interface of the class. This is not possible, because this function is defined in a protected visibility and this code is not part of a decendantclass, friend class, or other such code that should be able to see protected functions of the Laser class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Authors ==&lt;br /&gt;
Original author: Xoren Raymaker, April 18, 2007.&amp;lt;br&amp;gt;&lt;br /&gt;
I realize this might need some tweaking, but i&#039;m interested what your ideas and comments are about this idea of mine. It is a big thing to add to SL, but i think it could (in time) greatly enhance flexibility and features.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Related ideas ==&lt;br /&gt;
#[[Operator overloading]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Object_Oriented_LSL&amp;diff=17489</id>
		<title>Object Oriented LSL</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Object_Oriented_LSL&amp;diff=17489"/>
		<updated>2007-04-18T19:19:34Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This should be straight forward: Classes in LSL.&lt;br /&gt;
&lt;br /&gt;
Because it might not be clear why this is needed or how this would fit into currently existing LSL, I will try to make this clear through an example.&lt;br /&gt;
&lt;br /&gt;
To keep it simple, this object has two prims, one base and one prim simulating the laser light. The laser light prim contains two scripts and the base prim contains one script, which uses code, written in the two other scripts.&lt;br /&gt;
&lt;br /&gt;
== Class Declaration ==&lt;br /&gt;
This is the first script, containing the interface of a script library, containing the interface of a class.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type libraryinterface;&lt;br /&gt;
&lt;br /&gt;
!exports class Laser;&lt;br /&gt;
&lt;br /&gt;
class Laser: inherits llcConePrim&lt;br /&gt;
{&lt;br /&gt;
  protected&lt;br /&gt;
    function SetPosition(vector pos); override;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create(); override;&lt;br /&gt;
    destructor Destroy(); override;&lt;br /&gt;
&lt;br /&gt;
    function SwitchOn();&lt;br /&gt;
    function SwitchOff();&lt;br /&gt;
&lt;br /&gt;
    function SetColor(colorandalpha rgba); override;&lt;br /&gt;
    function GetColor(): colorandalpha; override;&lt;br /&gt;
&lt;br /&gt;
    property Color: colorandalpha; read GetColor write SetColor;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script introduces a few things yet unknown in LSL, none of which are (at the time of writing) documented feature requests. First line in this script specifies that this script is of a different type than a normal script. It is in fact the interface of a script library. It knows a counterpart called a libraryimplementation, which we will find in the second script. This is done because someone who wants to use the script library, needs to know it&#039;s interface, so these interface scripts need to be viewable by other users, but you might want to protect the implementation part of the library, so hence two scripts are needed, so that one can be viewable and the other not viewable.&lt;br /&gt;
The next line we find, contains an !exports keyword, which says &amp;quot;this script exports something that should be able to be used by other scripts&amp;quot;. In this case, it exports the class &amp;quot;Laser&amp;quot;, which is defined after this.&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; The keywords !type and !exports are both prefixed by an exclamation mark (!) because they tell something about the script itself. They could be seen as extra (optional) properties to a script.&lt;br /&gt;
&amp;lt;b&amp;gt;Note2:&amp;lt;/b&amp;gt; I will not explain in depth here what everything means, i will assume therefor that the general concept and terminology of classes is known.&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Class ===&lt;br /&gt;
Now the actual subject of this feature request. The next line after the !exports keyword begins the definition of a class called &amp;quot;Laser&amp;quot;. Straight into it, we also specify that it inherits from llcConePrim, which would be the base class representing all cone shaped prims. The llcConePrim itself then inherits from the basic llcPrim which would be the base class for all prims.&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Protected ===&lt;br /&gt;
Inside the class declaration, we find the keyword protected. This specifies that things defined after this keyword not available for use by all other code. Only members of the class itself, classes which inherit from this Laser class and classes which are &amp;quot;friends&amp;quot; of this Laser class, can &amp;quot;see&amp;quot; (and therefor use) the protected members declared.&lt;br /&gt;
&lt;br /&gt;
=== The Member Function ===&lt;br /&gt;
A class would be worth almost nothing if it didn&#039;t have member functions. Not much is to be said about these. The keyword &amp;quot;override&amp;quot; that follows it&#039;s declaration means &amp;quot;this functions overrides the functionality of a memberfunction with the same name in the base class&amp;quot;. Of cause this overriding can only be done if the function with this same name was defined as virtual in any of the ancestors. Besides override, there are many keywords to be invented here for use, like &amp;quot;reintroduce&amp;quot;, &amp;quot;abstract&amp;quot;, &amp;quot;overload&amp;quot;, etc.. I think that the idea of &amp;quot;abstract&amp;quot; (pure virtual) and &amp;quot;overload&amp;quot; is clear to most people.&lt;br /&gt;
The keyword &amp;quot;reintroduce&amp;quot; hides any functions of the same name from the inherited classes. Lets say a class A contains a virtual function &amp;quot;Test&amp;quot; with a parameter name as a string and a class B inherits from A and also implements the function Test, but does not have any parameters. You would then use the keyword reintroduce on the function B.Test, because this one reintroduces this functionality and you would not want a user of the class to use A.Test(...)&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Public ===&lt;br /&gt;
After the protected SetPosition member function we find the keyword public. This specifies that functions and such specified after this keyword are publicly available. In other words: every bit of code can &amp;quot;see&amp;quot; the things declared after the keyword public.&lt;br /&gt;
&lt;br /&gt;
=== Constructor and Destructor ===&lt;br /&gt;
The constructor and destructor are special memberfunctions. Every class has a constructor and destructor, but not every class needs to do anything special inside the constructor or destructor. The constructor and destructor are guaranteed to be called when an object of this class is created or destroyed. This way the object can do some initialization and finalization.&lt;br /&gt;
&lt;br /&gt;
=== Class Properties ===&lt;br /&gt;
Near to the end, we find a line defining a so called property with the name &amp;quot;Color&amp;quot;. This works almost like a variable and we will demonstrate this later. When we set the value of this property, the function SetColor will be used and when we will read out the value of the property, the function GetColor will be used to return the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Class implementation ==&lt;br /&gt;
Here is the second script, which contains the implementation of the class defined in the previous section.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type libraryimplementation;&lt;br /&gt;
&lt;br /&gt;
!implements class Laser;&lt;br /&gt;
&lt;br /&gt;
class Laser: inherits llcCubePrim&lt;br /&gt;
{&lt;br /&gt;
  private&lt;br /&gt;
    colorandalpha _Color;&lt;br /&gt;
    bool _State;&lt;br /&gt;
    key _id;&lt;br /&gt;
  protected&lt;br /&gt;
    function SetPosition(vector pos)&lt;br /&gt;
    {&lt;br /&gt;
      llSetPos(pos);&lt;br /&gt;
    }&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create()&lt;br /&gt;
    {&lt;br /&gt;
      _id = llGetKey();&lt;br /&gt;
      _State = false;&lt;br /&gt;
      _Color = &amp;lt;0,0,0,0&amp;gt;;&lt;br /&gt;
      llPrimHide();&lt;br /&gt;
      llTargetOmega(&amp;lt;0,0,0&amp;gt;, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
    destructor Destroy()&lt;br /&gt;
    {&lt;br /&gt;
      // Nothing to do..&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SwitchOn()&lt;br /&gt;
    {&lt;br /&gt;
      _State = true;&lt;br /&gt;
      llPrimShow();&lt;br /&gt;
      llTargetOmega(&amp;lt;1,0,0&amp;gt;, PI, 1);&lt;br /&gt;
    }&lt;br /&gt;
    function SwitchOff()&lt;br /&gt;
    {&lt;br /&gt;
      _State = false;&lt;br /&gt;
      llPrimHide();&lt;br /&gt;
      llTargetOmega(&amp;lt;0,0,0&amp;gt;, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SetColor(colorandalpha rgba)&lt;br /&gt;
    {&lt;br /&gt;
      _Color = rgba;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function GetColor(): colorandalpha&lt;br /&gt;
    {&lt;br /&gt;
      return _Color;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I&#039;ve use a few functions here that might not be actually existing functions, but for the sake of the simplicity of the example.. I don&#039;t know all functions yet, so i couldn&#039;t find a function for hiding and showing the prim the script is part of.&lt;br /&gt;
This shouls be pretty self explanatory, except at the beginning, we see the keyword !implements. This new keyword tells the scripting environment that this script implements the Laser class.&lt;br /&gt;
Further down this script, some people might wonder why the property Color was not present here. This is because properties are interface only. Think about it: What it there to implement on a property? A property only specifies how to read and (optionally) write the value.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
Now perhaps the most important part: How are we to use these classes? Well, remember the !exports keyword, which said that the class Laser was exported? We will now use that exported class in the base object.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type normal; // not needed, but one may specify if one wants to waste time of specifying this that are already default.. ;)&lt;br /&gt;
&lt;br /&gt;
!include LaserCone.LibraryInterfaceScript;&lt;br /&gt;
!include LaserCone.LibraryImplementationScript;&lt;br /&gt;
&lt;br /&gt;
Laser cone1, cone2;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1 = Laser.Create();&lt;br /&gt;
    cone1.Color = &amp;lt;0,1,0,1&amp;gt;;&lt;br /&gt;
    cone2 = Laser.Create();&lt;br /&gt;
    cone2.Color = &amp;lt;1,0,0,1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    state off;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state off&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1.SwitchOff();&lt;br /&gt;
    cone2.SwitchOff();&lt;br /&gt;
  }&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    state on;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state on&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1.SwitchOn();&lt;br /&gt;
    cone2.SwitchOn();&lt;br /&gt;
    llSetTimerEvent(1);&lt;br /&gt;
  }&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    llSetTimerEvent(0);&lt;br /&gt;
    state off;&lt;br /&gt;
  }&lt;br /&gt;
  timer()&lt;br /&gt;
  {&lt;br /&gt;
    float r = llFrand(1);&lt;br /&gt;
    float g = llFrand(1);&lt;br /&gt;
    float b = llFrand(1);&lt;br /&gt;
    cone1.Color = &amp;lt;r,g,b,1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    float r = llFrand(1);&lt;br /&gt;
    float g = llFrand(1);&lt;br /&gt;
    float b = llFrand(1);&lt;br /&gt;
    cone2.Color = &amp;lt;r,g,b,1&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Well, most of this should be a piece of cake, really, except, perhaps, the lines containing the !include keyword. This keyword specifies that this this script would like to use code in a different script. In this case, I immediately went a step further than the basics, including a script which is not part of the content of the same prim, but which is inside a different prim. The prim which contains the scripts in this example is called &amp;quot;LaserCone&amp;quot; and the two scripts are called LibraryInterfaceScript and LibraryImplementationScript.&lt;br /&gt;
Any script from any prim in the set may be included, but only things that are actually exported can be used. In this case, the implementation script does not export anything. It only implements the interface of the Laser class. The interface script does export something: the Laser class, so the last script may use it.&lt;br /&gt;
&lt;br /&gt;
In the state_entry() of the default state, we see two Laser objects are created, stored in the variables cone1 and cone2. Also their Color is set. Pure green for cone1 and pure red for cone2. The way the color is specified here is not currently possible in LSL, but i like to think about color as a 4D vector, including red, green, blue and alpha values, which makes it easier to specify color. Also, OpenGL accepts color this way through glColor4f(r, g, b, a), so it might be better, performance wise, to do it like this. Here, i mostly used it for the sake of the example. It also makes the example class a lot tighter than including a seperate alpha property and set and get methods.&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; From this script, it is impossible to call the SetPosition function, defined in the interface of the class. This is not possible, because this function is defined in a protected visibility and this code is not part of a decendantclass, friend class, or other such code that should be able to see protected functions of the Laser class.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
Original author: Xoren Raymaker, April 18, 2007.&amp;lt;br&amp;gt;&lt;br /&gt;
I realize this might need some tweaking, but i&#039;m interested what your ideas, comments are about this idea of mine. It is a big thing to add to SL, but i think it could (in time) greatly enhance flexibility and features.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;b&amp;gt;(Other) related ideas:&amp;lt;/b&amp;gt;&lt;br /&gt;
#[[Operator overloading]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Object_Oriented_LSL&amp;diff=17488</id>
		<title>Object Oriented LSL</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Object_Oriented_LSL&amp;diff=17488"/>
		<updated>2007-04-18T19:10:43Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This should be straight forward: Classes in LSL.&lt;br /&gt;
&lt;br /&gt;
Because it might not be clear why this is needed or how this would fit into currently existing LSL, I will try to make this clear through an example.&lt;br /&gt;
&lt;br /&gt;
To keep it simple, this object has two prims, one base and one prim simulating the laser light. The laser light prim contains two scripts and the base prim contains one script, which uses code, written in the two other scripts.&lt;br /&gt;
&lt;br /&gt;
== Class Declaration ==&lt;br /&gt;
This is the first script, containing the interface of a script library, containing the interface of a class.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type libraryinterface;&lt;br /&gt;
&lt;br /&gt;
!exports class Laser;&lt;br /&gt;
&lt;br /&gt;
class Laser: inherits llcConePrim&lt;br /&gt;
{&lt;br /&gt;
  protected&lt;br /&gt;
    function SetPosition(vector pos); override;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create(); override;&lt;br /&gt;
    destructor Destroy(); override;&lt;br /&gt;
&lt;br /&gt;
    function SwitchOn();&lt;br /&gt;
    function SwitchOff();&lt;br /&gt;
&lt;br /&gt;
    function SetColor(colorandalpha rgba); override;&lt;br /&gt;
    function GetColor(): colorandalpha; override;&lt;br /&gt;
&lt;br /&gt;
    property Color: colorandalpha; read GetColor write SetColor;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script introduces a few things yet unknown in LSL, none of which are (at the time of writing) documented feature requests. First line in this script specifies that this script is of a different type than a normal script. It is in fact the interface of a script library. It knows a counterpart called a libraryimplementation, which we will find in the second script. This is done because someone who wants to use the script library, needs to know it&#039;s interface, so these interface scripts need to be viewable by other users, but you might want to protect the implementation part of the library, so hence two scripts are needed, so that one can be viewable and the other not viewable.&lt;br /&gt;
The next line we find, contains an !exports keyword, which says &amp;quot;this script exports something that should be able to be used by other scripts&amp;quot;. In this case, it exports the class &amp;quot;Laser&amp;quot;, which is defined after this.&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; The keywords !type and !exports are both prefixed by an exclamation mark (!) because they tell something about the script itself. They could be seen as extra (optional) properties to a script.&lt;br /&gt;
&amp;lt;b&amp;gt;Note2:&amp;lt;/b&amp;gt; I will not explain in depth here what everything means, i will assume therefor that the general concept and terminology of classes is known.&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Class ===&lt;br /&gt;
Now the actual subject of this feature request. The next line after the !exports keyword begins the definition of a class called &amp;quot;Laser&amp;quot;. Straight into it, we also specify that it inherits from llcConePrim, which would be the base class representing all cone shaped prims. The llcConePrim itself then inherits from the basic llcPrim which would be the base class for all prims.&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Protected ===&lt;br /&gt;
Inside the class declaration, we find the keyword protected. This specifies that things defined after this keyword not available for use by all other code. Only members of the class itself, classes which inherit from this Laser class and classes which are &amp;quot;friends&amp;quot; of this Laser class, can &amp;quot;see&amp;quot; (and therefor use) the protected members declared.&lt;br /&gt;
&lt;br /&gt;
=== The Member Function ===&lt;br /&gt;
A class would be worth almost nothing if it didn&#039;t have member functions. Not much is to be said about these. The keyword &amp;quot;override&amp;quot; that follows it&#039;s declaration means &amp;quot;this functions overrides the functionality of a memberfunction with the same name in the base class&amp;quot;. Of cause this overriding can only be done if the function with this same name was defined as virtual in any of the ancestors. Besides override, there are many keywords to be invented here for use, like &amp;quot;reintroduce&amp;quot;, &amp;quot;abstract&amp;quot;, &amp;quot;overload&amp;quot;, etc.. I think that the idea of &amp;quot;abstract&amp;quot; (pure virtual) and &amp;quot;overload&amp;quot; is clear to most people.&lt;br /&gt;
The keyword &amp;quot;reintroduce&amp;quot; hides any functions of the same name from the inherited classes. Lets say a class A contains a virtual function &amp;quot;Test&amp;quot; with a parameter name as a string and a class B inherits from A and also implements the function Test, but does not have any parameters. You would then use the keyword reintroduce on the function B.Test, because this one reintroduces this functionality and you would not want a user of the class to use A.Test(...)&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Public ===&lt;br /&gt;
After the protected SetPosition member function we find the keyword public. This specifies that functions and such specified after this keyword are publicly available. In other words: every bit of code can &amp;quot;see&amp;quot; the things declared after the keyword public.&lt;br /&gt;
&lt;br /&gt;
=== Constructor and Destructor ===&lt;br /&gt;
The constructor and destructor are special memberfunctions. Every class has a constructor and destructor, but not every class needs to do anything special inside the constructor or destructor. The constructor and destructor are guaranteed to be called when an object of this class is created or destroyed. This way the object can do some initialization and finalization.&lt;br /&gt;
&lt;br /&gt;
=== Class Properties ===&lt;br /&gt;
Near to the end, we find a line defining a so called property with the name &amp;quot;Color&amp;quot;. This works almost like a variable and we will demonstrate this later. When we set the value of this property, the function SetColor will be used and when we will read out the value of the property, the function GetColor will be used to return the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Class implementation ==&lt;br /&gt;
Here is the second script, which contains the implementation of the class defined in the previous section.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type libraryimplementation;&lt;br /&gt;
&lt;br /&gt;
!implements class Laser;&lt;br /&gt;
&lt;br /&gt;
class Laser: inherits llcCubePrim&lt;br /&gt;
{&lt;br /&gt;
  private&lt;br /&gt;
    colorandalpha _Color;&lt;br /&gt;
    bool _State;&lt;br /&gt;
    key _id;&lt;br /&gt;
  protected&lt;br /&gt;
    function SetPosition(vector pos)&lt;br /&gt;
    {&lt;br /&gt;
      llSetPos(pos);&lt;br /&gt;
    }&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create()&lt;br /&gt;
    {&lt;br /&gt;
      _id = llGetKey();&lt;br /&gt;
      _State = false;&lt;br /&gt;
      _Color = &amp;lt;0,0,0,0&amp;gt;;&lt;br /&gt;
      llPrimHide();&lt;br /&gt;
      llTargetOmega(&amp;lt;0,0,0&amp;gt;, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
    destructor Destroy()&lt;br /&gt;
    {&lt;br /&gt;
      // Nothing to do..&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SwitchOn()&lt;br /&gt;
    {&lt;br /&gt;
      _State = true;&lt;br /&gt;
      llPrimShow();&lt;br /&gt;
      llTargetOmega(&amp;lt;1,0,0&amp;gt;, PI, 1);&lt;br /&gt;
    }&lt;br /&gt;
    function SwitchOff()&lt;br /&gt;
    {&lt;br /&gt;
      _State = false;&lt;br /&gt;
      llPrimHide();&lt;br /&gt;
      llTargetOmega(&amp;lt;0,0,0&amp;gt;, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SetColor(colorandalpha rgba)&lt;br /&gt;
    {&lt;br /&gt;
      _Color = rgba;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function GetColor(): colorandalpha&lt;br /&gt;
    {&lt;br /&gt;
      return _Color;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I&#039;ve use a few functions here that might not be actually existing functions, but for the sake of the simplicity of the example.. I don&#039;t know all functions yet, so i couldn&#039;t find a function for hiding and showing the prim the script is part of.&lt;br /&gt;
This shouls be pretty self explanatory, except at the beginning, we see the keyword !implements. This new keyword tells the scripting environment that this script implements the Laser class.&lt;br /&gt;
Further down this script, some people might wonder why the property Color was not present here. This is because properties are interface only. Think about it: What it there to implement on a property? A property only specifies how to read and (optionally) write the value.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
Now perhaps the most important part: How are we to use these classes? Well, remember the !exports keyword, which said that the class Laser was exported? We will now use that exported class in the base object.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type normal; // not needed, but one may specify if one wants to waste time of specifying this that are already default.. ;)&lt;br /&gt;
&lt;br /&gt;
!include LaserCone.LibraryInterfaceScript;&lt;br /&gt;
!include LaserCone.LibraryImplementationScript;&lt;br /&gt;
&lt;br /&gt;
Laser cone1, cone2;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1 = Laser.Create();&lt;br /&gt;
    cone1.Color = &amp;lt;0,1,0,1&amp;gt;;&lt;br /&gt;
    cone2 = Laser.Create();&lt;br /&gt;
    cone2.Color = &amp;lt;1,0,0,1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    state off;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state off&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1.SwitchOff();&lt;br /&gt;
    cone2.SwitchOff();&lt;br /&gt;
  }&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    state on;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state on&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1.SwitchOn();&lt;br /&gt;
    cone2.SwitchOn();&lt;br /&gt;
    llSetTimerEvent(1);&lt;br /&gt;
  }&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    llSetTimerEvent(0);&lt;br /&gt;
    state off;&lt;br /&gt;
  }&lt;br /&gt;
  timer()&lt;br /&gt;
  {&lt;br /&gt;
    float r = llFrand(1);&lt;br /&gt;
    float g = llFrand(1);&lt;br /&gt;
    float b = llFrand(1);&lt;br /&gt;
    cone1.Color = &amp;lt;r,g,b,1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    float r = llFrand(1);&lt;br /&gt;
    float g = llFrand(1);&lt;br /&gt;
    float b = llFrand(1);&lt;br /&gt;
    cone2.Color = &amp;lt;r,g,b,1&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Well, most of this should be a piece of cake, really, except, perhaps, the lines containing the !include keyword. This keyword specifies that this this script would like to use code in a different script. In this case, I immediately went a step further than the basics, including a script which is not part of the content of the same prim, but which is inside a different prim. The prim which contains the scripts in this example is called &amp;quot;LaserCone&amp;quot; and the two scripts are called LibraryInterfaceScript and LibraryImplementationScript.&lt;br /&gt;
Any script from any prim in the set may be included, but only things that are actually exported can be used. In this case, the implementation script does not export anything. It only implements the interface of the Laser class. The interface script does export something: the Laser class, so the last script may use it.&lt;br /&gt;
&lt;br /&gt;
In the state_entry() of the default state, we see two Laser objects are created, stored in the variables cone1 and cone2. Also their Color is set. Pure green for cone1 and pure red for cone2. The way the color is specified here is not currently possible in LSL, but i like to think about color as a 4D vector, including red, green, blue and alpha values, which makes it easier to specify color. Also, OpenGL accepts color this way through glColor4f(r, g, b, a), so it might be better, performance wise, to do it like this. Here, i mostly used it for the sake of the example. It also makes the example class a lot tighter than including a seperate alpha property and set and get methods.&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; From this script, it is impossible to call the SetPosition function, defined in the interface of the class. This is not possible, because this function is defined in a protected visibility and this code is not part of a decendantclass, friend class, or other such code that should be able to see protected functions of the Laser class.&lt;br /&gt;
&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Object_Oriented_LSL&amp;diff=17486</id>
		<title>Object Oriented LSL</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Object_Oriented_LSL&amp;diff=17486"/>
		<updated>2007-04-18T19:01:25Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This should be straight forward: Classes in LSL.&lt;br /&gt;
&lt;br /&gt;
Because it might not be clear why this is needed or how this would fit into currently existing LSL, I will try to make this clear through an example.&lt;br /&gt;
&lt;br /&gt;
To keep it simple, this object has two prims, one base and one prim simulating the laser light. The laser light prim contains two scripts and the base prim contains one script, which uses code, written in the two other scripts.&lt;br /&gt;
&lt;br /&gt;
== Class Declaration ==&lt;br /&gt;
This is the first script, containing the interface of a script library, containing the interface of a class.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type libraryinterface;&lt;br /&gt;
&lt;br /&gt;
!exports class Laser;&lt;br /&gt;
&lt;br /&gt;
class Laser: inherits llcConePrim&lt;br /&gt;
{&lt;br /&gt;
  protected&lt;br /&gt;
    function SetPosition(vector pos); override;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create(); override;&lt;br /&gt;
    destructor Destroy(); override;&lt;br /&gt;
&lt;br /&gt;
    function SwitchOn();&lt;br /&gt;
    function SwitchOff();&lt;br /&gt;
&lt;br /&gt;
    function SetColor(colorandalpha rgba); override;&lt;br /&gt;
    function GetColor(): colorandalpha; override;&lt;br /&gt;
&lt;br /&gt;
    property Color: colorandalpha; read GetColor write SetColor;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script introduces a few things yet unknown in LSL, none of which are (at the time of writing) documented feature requests. First line in this script specifies that this script is of a different type than a normal script. It is in fact the interface of a script library. It knows a counterpart called a libraryimplementation, which we will find in the second script. This is done because someone who wants to use the script library, needs to know it&#039;s interface, so these interface scripts need to be viewable by other users, but you might want to protect the implementation part of the library, so hence two scripts are needed, so that one can be viewable and the other not viewable.&lt;br /&gt;
The next line we find, contains an !exports keyword, which says &amp;quot;this script exports something that should be able to be used by other scripts&amp;quot;. In this case, it exports the class &amp;quot;Laser&amp;quot;, which is defined after this.&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; The keywords !type and !exports are both prefixed by an exclamation mark (!) because they tell something about the script itself. They could be seen as extra (optional) properties to a script.&lt;br /&gt;
&amp;lt;b&amp;gt;Note2:&amp;lt;/b&amp;gt; I will not explain in depth here what everything means, i will assume therefor that the general concept and terminology of classes is known.&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Class ===&lt;br /&gt;
Now the actual subject of this feature request. The next line after the !exports keyword begins the definition of a class called &amp;quot;Laser&amp;quot;. Straight into it, we also specify that it inherits from llcConePrim, which would be the base class representing all cone shaped prims. The llcConePrim itself then inherits from the basic llcPrim which would be the base class for all prims.&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Protected ===&lt;br /&gt;
Inside the class declaration, we find the keyword protected. This specifies that things defined after this keyword not available for use by all other code. Only members of the class itself, classes which inherit from this Laser class and classes which are &amp;quot;friends&amp;quot; of this Laser class, can &amp;quot;see&amp;quot; (and therefor use) the protected members declared.&lt;br /&gt;
&lt;br /&gt;
=== The Member Function ===&lt;br /&gt;
A class would be worth almost nothing if it didn&#039;t have member functions. Not much is to be said about these. The keyword &amp;quot;override&amp;quot; that follows it&#039;s declaration means &amp;quot;this functions overrides the functionality of a memberfunction with the same name in the base class&amp;quot;. Of cause this overriding can only be done if the function with this same name was defined as virtual in any of the ancestors. Besides override, there are many keywords to be invented here for use, like &amp;quot;reintroduce&amp;quot;, &amp;quot;abstract&amp;quot;, &amp;quot;overload&amp;quot;, etc.. I think that the idea of &amp;quot;abstract&amp;quot; (pure virtual) and &amp;quot;overload&amp;quot; is clear to most people.&lt;br /&gt;
The keyword &amp;quot;reintroduce&amp;quot; hides any functions of the same name from the inherited classes. Lets say a class A contains a virtual function &amp;quot;Test&amp;quot; with a parameter name as a string and a class B inherits from A and also implements the function Test, but does not have any parameters. You would then use the keyword reintroduce on the function B.Test, because this one reintroduces this functionality and you would not want a user of the class to use A.Test(...)&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Public ===&lt;br /&gt;
After the protected SetPosition member function we find the keyword public. This specifies that functions and such specified after this keyword are publicly available. In other words: every bit of code can &amp;quot;see&amp;quot; the things declared after the keyword public.&lt;br /&gt;
&lt;br /&gt;
=== Constructor and Destructor ===&lt;br /&gt;
The constructor and destructor are special memberfunctions. Every class has a constructor and destructor, but not every class needs to do anything special inside the constructor or destructor. The constructor and destructor are guaranteed to be called when an object of this class is created or destroyed. This way the object can do some initialization and finalization.&lt;br /&gt;
&lt;br /&gt;
=== Class Properties ===&lt;br /&gt;
Near to the end, we find a line defining a so called property with the name &amp;quot;Color&amp;quot;. This works almost like a variable and we will demonstrate this later. When we set the value of this property, the function SetColor will be used and when we will read out the value of the property, the function GetColor will be used to return the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Class implementation ==&lt;br /&gt;
Here is the second script, which contains the implementation of the class defined in the previous section.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type libraryimplementation;&lt;br /&gt;
&lt;br /&gt;
!implements class Laser;&lt;br /&gt;
&lt;br /&gt;
class Laser: inherits llcCubePrim&lt;br /&gt;
{&lt;br /&gt;
  private&lt;br /&gt;
    colorandalpha _Color;&lt;br /&gt;
    bool _State;&lt;br /&gt;
    key _id;&lt;br /&gt;
  protected&lt;br /&gt;
    function SetPosition(vector pos)&lt;br /&gt;
    {&lt;br /&gt;
      llSetPos(pos);&lt;br /&gt;
    }&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create()&lt;br /&gt;
    {&lt;br /&gt;
      _id = llGetKey();&lt;br /&gt;
      _State = false;&lt;br /&gt;
      _Color = &amp;lt;0,0,0,0&amp;gt;;&lt;br /&gt;
      llPrimHide();&lt;br /&gt;
      llTargetOmega(&amp;lt;0,0,0&amp;gt;, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
    destructor Destroy()&lt;br /&gt;
    {&lt;br /&gt;
      // Nothing to do..&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SwitchOn()&lt;br /&gt;
    {&lt;br /&gt;
      _State = true;&lt;br /&gt;
      llPrimShow();&lt;br /&gt;
      llTargetOmega(&amp;lt;1,0,0&amp;gt;, PI, 1);&lt;br /&gt;
    }&lt;br /&gt;
    function SwitchOff()&lt;br /&gt;
    {&lt;br /&gt;
      _State = false;&lt;br /&gt;
      llPrimHide();&lt;br /&gt;
      llTargetOmega(&amp;lt;0,0,0&amp;gt;, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SetColor(colorandalpha rgba)&lt;br /&gt;
    {&lt;br /&gt;
      _Color = rgba;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function GetColor(): colorandalpha&lt;br /&gt;
    {&lt;br /&gt;
      return _Color;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I&#039;ve use a few functions here that might not be actually existing functions, but for the sake of the simplicity of the example.. I don&#039;t know all functions yet, so i couldn&#039;t find a function for hiding and showing the prim the script is part of.&lt;br /&gt;
This shouls be pretty self explanatory, except at the beginning, we see the keyword !implements. This new keyword tells the scripting environment that this script implements the Laser class.&lt;br /&gt;
Further down this script, some people might wonder why the property Color was not present here. This is because properties are interface only. Think about it: What it there to implement on a property? A property only specifies how to read and (optionally) write the value.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
Now perhaps the most important part: How are we to use these classes? Well, remember the !exports keyword, which said that the class Laser was exported? We will now use that exported class in the base object.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type normal; // not needed, but one may specify if one wants to waste time of specifying this that are already default.. ;)&lt;br /&gt;
&lt;br /&gt;
!include LaserCone.LibraryInterfaceScript;&lt;br /&gt;
!include LaserCone.LibraryImplementationScript;&lt;br /&gt;
&lt;br /&gt;
Laser cone1, cone2;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1 = Laser.Create();&lt;br /&gt;
    cone1.Color = &amp;lt;0,1,0,1&amp;gt;;&lt;br /&gt;
    cone2 = Laser.Create();&lt;br /&gt;
    cone2.Color = &amp;lt;1,0,0,1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    state off;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state off&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1.SwitchOff();&lt;br /&gt;
    cone2.SwitchOff();&lt;br /&gt;
  }&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    state on;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state on&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1.SwitchOn();&lt;br /&gt;
    cone2.SwitchOn();&lt;br /&gt;
    llSetTimerEvent(1);&lt;br /&gt;
  }&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    llSetTimerEvent(0);&lt;br /&gt;
    state off;&lt;br /&gt;
  }&lt;br /&gt;
  timer()&lt;br /&gt;
  {&lt;br /&gt;
    float r = llFrand(1);&lt;br /&gt;
    float g = llFrand(1);&lt;br /&gt;
    float b = llFrand(1);&lt;br /&gt;
    cone1.Color = &amp;lt;r,g,b,1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    float r = llFrand(1);&lt;br /&gt;
    float g = llFrand(1);&lt;br /&gt;
    float b = llFrand(1);&lt;br /&gt;
    cone2.Color = &amp;lt;r,g,b,1&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Well, most of this should be a piece of cake, really, except, perhaps, the lines containing the !include keyword. This keyword specifies that this this script would like to use code in a different script. In this case, I immediately went a step further than the basics, including a script which is not part of the content of the same prim, but which is inside a different prim. The prim which contains the scripts in this example is called &amp;quot;LaserCone&amp;quot; and the two scripts are called LibraryInterfaceScript and LibraryImplementationScript.&lt;br /&gt;
Any script from any prim in the set may be included, but only things that are actually exported can be used. In this case, the implementation script does not export anything. It only implements the interface of the Laser class. The interface script does export something: the Laser class, so the last script may use it.&lt;br /&gt;
&lt;br /&gt;
In the state_entry() of the default state, we see two Laser objects are created, stored in the variables cone1 and cone2. Also their Color is set. Pure green for cone1 and pure red for cone2. The way the color is specified here is not currently possible in LSL, but i like to think about color as a 4D vector, including red, green, blue and alpha values, which makes it easier to specify color. Also, OpenGL accepts color this way through glColor4f(r, g, b, a), so it might be better, performance wise, to do it like this. Here, i mostly used it for the sake of the example. It also makes the example class a lot tighter than including a seperate alpha property and set and get methods.&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; From this script, it is impossible to call the SetPosition function, defined in the interface of the class. This is not possible, because this function is defined in a protected visibility and this code is not part of a decendantclass, friend class, or other such code that should be able to see protected functions of the Laser class.&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Object_Oriented_LSL&amp;diff=17485</id>
		<title>Object Oriented LSL</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Object_Oriented_LSL&amp;diff=17485"/>
		<updated>2007-04-18T18:45:20Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This should be straight forward: Classes in LSL.&lt;br /&gt;
&lt;br /&gt;
Because it might not be clear why this is needed or how this would fit into currently existing LSL, I will try to make this clear through an example.&lt;br /&gt;
&lt;br /&gt;
To keep it simple, this object has two prims, one base and one prim simulating the laser light. The laser light prim contains two scripts and the base prim contains one script, which uses code, written in the two other scripts.&lt;br /&gt;
&lt;br /&gt;
== Class Declaration ==&lt;br /&gt;
This is the first script, containing the interface of a script library, containing the interface of a class.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type libraryinterface;&lt;br /&gt;
&lt;br /&gt;
!exports class Laser;&lt;br /&gt;
&lt;br /&gt;
class Laser: inherits llcConePrim&lt;br /&gt;
{&lt;br /&gt;
  protected&lt;br /&gt;
    function SetPosition(vector pos); override;&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create(); override;&lt;br /&gt;
    destructor Destroy(); override;&lt;br /&gt;
&lt;br /&gt;
    function SwitchOn();&lt;br /&gt;
    function SwitchOff();&lt;br /&gt;
&lt;br /&gt;
    function SetColor(colorandalpha rgba); override;&lt;br /&gt;
    function GetColor(): colorandalpha; override;&lt;br /&gt;
&lt;br /&gt;
    property Color: colorandalpha; read GetColor write SetColor;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This script introduces a few things yet unknown in LSL, none of which are (at the time of writing) documented feature requests. First line in this script specifies that this script is of a different type than a normal script. It is in fact the interface of a script library. It knows a counterpart called a libraryimplementation, which we will find in the second script. This is done because someone who wants to use the script library, needs to know it&#039;s interface, so these interface scripts need to be viewable by other users, but you might want to protect the implementation part of the library, so hence two scripts are needed, so that one can be viewable and the other not viewable.&lt;br /&gt;
The next line we find, contains an !exports keyword, which says &amp;quot;this script exports something that should be able to be used by other scripts&amp;quot;. In this case, it exports the class &amp;quot;Laser&amp;quot;, which is defined after this.&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; The keywords !type and !exports are both prefixed by an exclamation mark (!) because they tell something about the script itself. They could be seen as extra (optional) properties to a script.&lt;br /&gt;
&amp;lt;b&amp;gt;Note2:&amp;lt;/b&amp;gt; I will not explain in depth here what everything means, i will assume therefor that the general concept and terminology of classes is known.&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Class ===&lt;br /&gt;
Now the actual subject of this feature request. The next line after the !exports keyword begins the definition of a class called &amp;quot;Laser&amp;quot;. Straight into it, we also specify that it inherits from llcConePrim, which would be the base class representing all cone shaped prims. The llcConePrim itself then inherits from the basic llcPrim which would be the base class for all prims.&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Protected ===&lt;br /&gt;
Inside the class declaration, we find the keyword protected. This specifies that things defined after this keyword not available for use by all other code. Only members of the class itself, classes which inherit from this Laser class and classes which are &amp;quot;friends&amp;quot; of this Laser class, can &amp;quot;see&amp;quot; (and therefor use) the protected members declared.&lt;br /&gt;
&lt;br /&gt;
=== The Member Function ===&lt;br /&gt;
A class would be worth almost nothing if it didn&#039;t have member functions. Not much is to be said about these. The keyword &amp;quot;override&amp;quot; that follows it&#039;s declaration means &amp;quot;this functions overrides the functionality of a memberfunction with the same name in the base class&amp;quot;. Of cause this overriding can only be done if the function with this same name was defined as virtual in any of the ancestors. Besides override, there are many keywords to be invented here for use, like &amp;quot;reintroduce&amp;quot;, &amp;quot;abstract&amp;quot;, &amp;quot;overload&amp;quot;, etc.. I think that the idea of &amp;quot;abstract&amp;quot; (pure virtual) and &amp;quot;overload&amp;quot; is clear to most people.&lt;br /&gt;
The keyword &amp;quot;reintroduce&amp;quot; hides any functions of the same name from the inherited classes. Lets say a class A contains a virtual function &amp;quot;Test&amp;quot; with a parameter name as a string and a class B inherits from A and also implements the function Test, but does not have any parameters. You would then use the keyword reintroduce on the function B.Test, because this one reintroduces this functionality and you would not want a user of the class to use A.Test(...)&lt;br /&gt;
&lt;br /&gt;
=== The Keyword Public ===&lt;br /&gt;
After the protected SetPosition member function we find the keyword public. This specifies that functions and such specified after this keyword are publicly available. In other words: every bit of code can &amp;quot;see&amp;quot; the things declared after the keyword public.&lt;br /&gt;
&lt;br /&gt;
=== Constructor and Destructor ===&lt;br /&gt;
The constructor and destructor are special memberfunctions. Every class has a constructor and destructor, but not every class needs to do anything special inside the constructor or destructor. The constructor and destructor are guaranteed to be called when an object of this class is created or destroyed. This way the object can do some initialization and finalization.&lt;br /&gt;
&lt;br /&gt;
=== Class Properties ===&lt;br /&gt;
Near to the end, we find a line defining a so called property with the name &amp;quot;Color&amp;quot;. This works almost like a variable and we will demonstrate this later. When we set the value of this property, the function SetColor will be used and when we will read out the value of the property, the function GetColor will be used to return the value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Class implementation ==&lt;br /&gt;
Here is the second script, which contains the implementation of the class defined in the previous section.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type libraryimplementation;&lt;br /&gt;
&lt;br /&gt;
!implements class Laser;&lt;br /&gt;
&lt;br /&gt;
class Laser: inherits llcCubePrim&lt;br /&gt;
{&lt;br /&gt;
  private&lt;br /&gt;
    colorandalpha _Color;&lt;br /&gt;
    bool _State;&lt;br /&gt;
    key _id;&lt;br /&gt;
  protected&lt;br /&gt;
    function SetPosition(vector pos)&lt;br /&gt;
    {&lt;br /&gt;
      llSetPos(pos);&lt;br /&gt;
    }&lt;br /&gt;
  public&lt;br /&gt;
    constructor Create()&lt;br /&gt;
    {&lt;br /&gt;
      _id = llGetKey();&lt;br /&gt;
      _State = false;&lt;br /&gt;
      _Color = &amp;lt;0,0,0,0&amp;gt;;&lt;br /&gt;
      llPrimHide();&lt;br /&gt;
      llTargetOmega(&amp;lt;0,0,0&amp;gt;, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
    destructor Destroy()&lt;br /&gt;
    {&lt;br /&gt;
      // Nothing to do..&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SwitchOn()&lt;br /&gt;
    {&lt;br /&gt;
      _State = true;&lt;br /&gt;
      llPrimShow();&lt;br /&gt;
      llTargetOmega(&amp;lt;1,0,0&amp;gt;, PI, 1);&lt;br /&gt;
    }&lt;br /&gt;
    function SwitchOff()&lt;br /&gt;
    {&lt;br /&gt;
      _State = false;&lt;br /&gt;
      llPrimHide();&lt;br /&gt;
      llTargetOmega(&amp;lt;0,0,0&amp;gt;, 0, 0);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function SetColor(colorandalpha rgba)&lt;br /&gt;
    {&lt;br /&gt;
      _Color = rgba;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    function GetColor(): colorandalpha&lt;br /&gt;
    {&lt;br /&gt;
      return _Color;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I&#039;ve use a few functions here that might not be actually existing functions, but for the sake of the simplicity of the example.. I don&#039;t know all functions yet, so i couldn&#039;t find a function for hiding and showing the prim the script is part of.&lt;br /&gt;
This shouls be pretty self explanatory, except at the beginning, we see the keyword !implements. This new keyword tells the scripting environment that this script implements the Laser class.&lt;br /&gt;
Further down this script, some people might wonder why the property Color was not present here. This is because properties are interface only. Think about it: What it there to implement on a property? A property only specifies how to read and (optionally) write the value.&lt;br /&gt;
&lt;br /&gt;
== Usage ==&lt;br /&gt;
Now perhaps the most important part: How are we to use these classes? Well, remember the !exports keyword, which said that the class Laser was exported? We will now use that exported class in the base object.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
!type normal; // not needed, but one may specify if one wants to waste time of specifying this that are already default.. ;)&lt;br /&gt;
&lt;br /&gt;
!include LaserCone.LibraryInterfaceScript;&lt;br /&gt;
!include LaserCone.LibraryImplementationScript;&lt;br /&gt;
&lt;br /&gt;
Laser cone1, cone2;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1 = Laser.Create();&lt;br /&gt;
    cone1.Color = &amp;lt;0,1,0,1&amp;gt;;&lt;br /&gt;
    cone2 = Laser.Create();&lt;br /&gt;
    cone2.Color = &amp;lt;1,0,0,1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    state off;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state off&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1.SwitchOff();&lt;br /&gt;
    cone2.SwitchOff();&lt;br /&gt;
  }&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    state on;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
state on&lt;br /&gt;
{&lt;br /&gt;
  state_entry()&lt;br /&gt;
  {&lt;br /&gt;
    cone1.SwitchOn();&lt;br /&gt;
    cone2.SwitchOn();&lt;br /&gt;
    llSetTimerEvent(1);&lt;br /&gt;
  }&lt;br /&gt;
  touch_start(integer num)&lt;br /&gt;
  {&lt;br /&gt;
    llSetTimerEvent(0);&lt;br /&gt;
    state off;&lt;br /&gt;
  }&lt;br /&gt;
  timer()&lt;br /&gt;
  {&lt;br /&gt;
    float r = llFrand(1);&lt;br /&gt;
    float g = llFrand(1);&lt;br /&gt;
    float b = llFrand(1);&lt;br /&gt;
    cone1.Color = &amp;lt;r,g,b,1&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
    float r = llFrand(1);&lt;br /&gt;
    float g = llFrand(1);&lt;br /&gt;
    float b = llFrand(1);&lt;br /&gt;
    cone2.Color = &amp;lt;r,g,b,1&amp;gt;;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Well, most of this should be a piece of cake, really. In the state_entry() of the default state, we see two Laser objects are created, stored in the variables cone1 and cone2. Also their Color is set. Pure green for cone1 and pure red for cone2. The way the color is specified here is not currently possible in LSL, but i like to think about color as a 4D vector, including red, green, blue and alpha values, which makes it easier to specify color. Also, OpenGL accepts color this way through glColor4f(r, g, b, a), so it might be better, performance wise, to do it like this. Here, i mostly used it for the sake of the example. It also makes the example class a lot tighter than including a seperate alpha property and set and get methods.&lt;br /&gt;
&amp;lt;b&amp;gt;Note:&amp;lt;/b&amp;gt; From this script, it is impossible to call the SetPosition function, defined in the interface of the class. This is not possible, because this function is defined in a protected visibility and this code is not part of a decendantclass, friend class, or other such code that should be able to see protected functions of the Laser class.&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Prim_and_Object_Hierarchy&amp;diff=17453</id>
		<title>Prim and Object Hierarchy</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Prim_and_Object_Hierarchy&amp;diff=17453"/>
		<updated>2007-04-18T01:09:20Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The problem ==&lt;br /&gt;
&lt;br /&gt;
Lets say that in SL we would want to make a human skeleton. When we want to do such correctly, we need to think about the bones and how they work together. Very soon we realize that if one bone moves, the bones which are connected to it and the bones connected to them, will follow the movement. Of cause, in the real world, this is only logical, but with a computer, this is a different story. It actually needs program code to make sure that the bones of the wrist, hand and fingers move along if the arm moves.&lt;br /&gt;
When you think about it, you see that the upper arm depends on the movement of the shoulder; the lower arm depends on the upper arm; the wrist depends on the lower arm, etc.. Clearly, there is a relation between these bones. This relation is often referred to as child and parent.&lt;br /&gt;
The shoulder in this example is the parent for the upper arm. The upper arm is itself then the parent to the lower arm, which is the parent for the wrist bone.&lt;br /&gt;
&lt;br /&gt;
In SL there is not such a relation between prims. It is possible to put several prims together in a set of linked prims, but if we would want to make something which needs a child-parent relation between prims, then the designer of the object needs to do this him or herself in LSL code, which is a difficult job that takes a lot of time and adds some extra code which makes the script less maintainable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The solution ==&lt;br /&gt;
&lt;br /&gt;
The solution is probably fairly easier for the user to understand than it is to make the changes to the viewer and server. For an easy solution, a prim could receive an extra flag indicating that it acts like a bone. If this flag is set (the box is ticked), then the prim has a few extra properties. Among which are a parent prim and child prim, but both are optional. In script some extra commands would be available:&lt;br /&gt;
&lt;br /&gt;
 prim llGetPrimParent(prim p);&lt;br /&gt;
   // This returns a pointer (be it a key, name or other) to the parent of the given prim.&lt;br /&gt;
 integer llGetPrimChildCount(prim p);&lt;br /&gt;
   // Returns the number of child prims linked to the given parent.&lt;br /&gt;
 prim llGetPrimChild(prim p, integer n);&lt;br /&gt;
   // Similar to llGetPrimParent(), but returns a pointer to the n&#039;th child.&lt;br /&gt;
 llSetPrimParent(prim child, prim parent);&lt;br /&gt;
   // This command takes two prims and links them by way of script. This is usefull for prims that are rezzed by script.&lt;br /&gt;
   // This sets the parent of the given child prim. Of cause it also sets the child of the given parent to the given child.&lt;br /&gt;
 llAddPrimChild(prim child, prim parent);&lt;br /&gt;
 llRemovePrimChild(prim child, prim parent);&lt;br /&gt;
   // Adds or removes a given child prim to the given parent prim. This seems to do the same as llSetPrimParent,&lt;br /&gt;
   // but there is a subtle difference. While a prim can only have one parent, it can have multiple children.&lt;br /&gt;
   // It is true that these can be used for most of the linkage, but the first prim in a chain never has a parent and to set this,&lt;br /&gt;
   // llSetPrimParent() is needed.&lt;br /&gt;
 llSetJointRotation(prim p, rotation rot);&lt;br /&gt;
   // This would set the angle between the given prim and it&#039;s parent. Thereby rotating it around the point where it meets it&#039;s parent.&lt;br /&gt;
 llSetSkinPoseRotation(prim p, rotation rot);&lt;br /&gt;
   // This would set a special angle value for the joint. It is called the skin pose, which is the rotation of the joint in a rest.&lt;br /&gt;
   // One might see the skin pose as the initial rotation or a rotation where you want the joint to reset to.&lt;br /&gt;
 llSetSkinPoseRotationAndPosition(prim p, rotation rot, vector pos, bool StretchConnectedPrims, bool MoveConnectedPrims);&lt;br /&gt;
   // Sometimes, it might be needed to also set the position of a child prim and stretch or move other prims accordingly.&lt;br /&gt;
 llSetSkinPose(prim p);&lt;br /&gt;
   // This is a command travels through the entire hierarchy and resets all the joints to their skin pose.&lt;br /&gt;
   // This should be just a bit faster than explicitly setting each joint to its skin pose from a script loop.&lt;br /&gt;
 llSetJointOmega(prim p, vector v, float speed, float time);&lt;br /&gt;
   // Like llSetTargetOmega(), but this one takes into account, the rotation of all the child prims.&lt;br /&gt;
   // By keeping two different commands for this, and the parent-child relationship needing probably a lot of extra code, it is&lt;br /&gt;
   // probably better to keep the function this one offers seperated from the existing llSetTargetOmega().&lt;br /&gt;
&lt;br /&gt;
More such commands could probably be invented. This allows for easy multi axis rotation of objects like disco lights and lots of other designs which need extra flexibility. -Xoren Raymaker&lt;br /&gt;
&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Prim_and_Object_Hierarchy&amp;diff=17452</id>
		<title>Prim and Object Hierarchy</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Prim_and_Object_Hierarchy&amp;diff=17452"/>
		<updated>2007-04-18T01:06:37Z</updated>

		<summary type="html">&lt;p&gt;Xoren Raymaker: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;This article is a feature request&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The problem ==&lt;br /&gt;
&lt;br /&gt;
Lets say that in SL we would want to make a human skeleton. When we want to do such correctly, we need to think about the bones and how they work together. Very soon we realize that if one bone moves, the bones which are connected to it and the bones connected to them, will follow the movement. Of cause, in the real world, this is only logical, but with a computer, this is a different story. It actually needs program code to make sure that the bones of the wrist, hand and fingers move along if the arm moves.&lt;br /&gt;
When you think about it, you see that the upper arm depends on the movement of the shoulder; the lower arm depends on the upper arm; the wrist depends on the lower arm, etc.. Clearly, there is a relation between these bones. This relation is often referred to as child and parent.&lt;br /&gt;
The shoulder in this example is the parent for the upper arm. The upper arm is itself then the parent to the lower arm, which is the parent for the wrist bone.&lt;br /&gt;
&lt;br /&gt;
In SL there is not such a relation between prims. It is possible to put several prims together in a set of linked prims, but if we would want to make something which needs a child-parent relation between prims, then the designer of the object needs to do this him or herself in LSL code, which is a difficult job that takes a lot of time and adds some extra code which makes the script less maintainable.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== The solution ==&lt;br /&gt;
&lt;br /&gt;
The solution is probably fairly easier for the user to understand than it is to make the changes to the viewer and server. For an easy solution, a prim could receive an extra flag indicating that it acts like a bone. If this flag is set (the box is ticked), then the prim has a few extra properties. Among which are a parent prim and child prim, but both are optional. In script some extra commands would be available:&lt;br /&gt;
&lt;br /&gt;
 prim llGetPrimParent(prim p);&lt;br /&gt;
   // This returns a pointer (be it a key, name or other) to the parent of the given prim.&lt;br /&gt;
 integer llGetPrimChildCount(prim p);&lt;br /&gt;
   // Returns the number of child prims linked to the given parent.&lt;br /&gt;
 prim llGetPrimChild(prim p, integer n);&lt;br /&gt;
   // Similar to llGetPrimParent(), but returns a pointer to the n&#039;th child.&lt;br /&gt;
 llSetPrimParent(prim child, prim parent);&lt;br /&gt;
   // This command takes two prims and links them by way of script. This is usefull for prims that are rezzed by script.&lt;br /&gt;
   // This sets the parent of the given child prim. Of cause it also sets the child of the given parent to the given child.&lt;br /&gt;
 llAddPrimChild(prim child, prim parent);&lt;br /&gt;
 llRemovePrimChild(prim child, prim parent);&lt;br /&gt;
   // Adds or removes a given child prim to the given parent prim. This seems to do the same as llSetPrimParent,&lt;br /&gt;
   // but there is a subtle difference. While a prim can only have one parent, it can have multiple children.&lt;br /&gt;
   // It is true that these can be used for most of the linkage, but the first prim in a chain never has a parent and to set this,&lt;br /&gt;
   // llSetPrimParent() is needed.&lt;br /&gt;
 llSetJointRotation(prim p, rotation rot);&lt;br /&gt;
   // This would set the angle between the given prim and it&#039;s parent. Thereby rotating it around the point where it meets it&#039;s parent.&lt;br /&gt;
 llSetSkinPoseRotation(prim p, rotation rot);&lt;br /&gt;
   // This would set a special angle value for the joint. It is called the skin pose, which is the rotation of the joint in a rest.&lt;br /&gt;
   // One might see the skin pose as the initial rotation or a rotation where you want the joint to reset to.&lt;br /&gt;
 llSetSkinPoseRotationAndPosition(prim p, rotation rot, vector pos, bool StretchConnectedPrims, bool MoveConnectedPrims);&lt;br /&gt;
   // Sometimes, it might be needed to also set the position of a child prim and stretch or move other prims accordingly.&lt;br /&gt;
 llSetSkinPose(prim p);&lt;br /&gt;
   // This is a command travels through the entire hierarchy and resets all the joints to their skin pose.&lt;br /&gt;
   // This should be just a bit faster than explicitly setting each joint to its skin pose from a script loop.&lt;br /&gt;
 llSetJointOmega(prim p, vector v, float speed, float time);&lt;br /&gt;
   // Like llSetTargetOmega(), but this one takes into account, the rotation of all the child prims.&lt;br /&gt;
   // By keeping two different commands for this, and the parent-child relationship needing probably a lot of extra code, it is&lt;br /&gt;
   // probably better to keep the function this one offers seperated from the existing llSetTargetOmega().&lt;br /&gt;
&lt;br /&gt;
More such commands could probably be invented. This allows for easy multi axis rotation of objects like disco lights and lots of other designs which need extra flexibility.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
[[User:Xoren Raymaker|Xoren Raymaker]]&lt;br /&gt;
[[Category:Feature Requests]]&lt;/div&gt;</summary>
		<author><name>Xoren Raymaker</name></author>
	</entry>
</feed>