tutorial de SLS Resumen Este es un resumen básico del Lenguaje de Programacion de Linden (Linden Scripting Language o LSL). En el trataré alguna información básica incluyendo: * * * * * * *
Sintaxis básica de LSL. Un recorrido linea a linea del script por defecto de LSL. Una descripción básica de manejadores de eventos, variables, funciones... Compilación de un script. El interface de usuario del editor de scripts. Donde conseguir scripts gratuitos. Recursos donde puedes acudir para obtener más ayuda.
introducción LSL es un lenguaje de programación que te permite programar acciones a cualquier objeto en Second Life. Por ejemplo, puedes hacer puertas que se abran cuando las tocas, luces que se muevan o brillen en diferentes colores, crear fuego, lluvia o nieve con partículas, o incluso crear un juego entero. Aprendiendo a programar ampliarás tus posibilidades creativas, ya que seras capaz de dotar de vida a tus objetos y hacerlos más interactivos. Programar es algo así como escribir las instrucciones de una receta de cocina. Generas una lista de instrucciones que han de ser realizadas en el mismo orden en que han sido escritas. La diferencia entre programar y escribir una receta, no obstante, es que un ordenador estará siguiendo tus instrucciones, y siempre las seguirá literalmente, hasta la ultima letra. Los ordenadores no tienen intuición, de hecho ellos son realmente un poco tontos, así que debes decirles todo lo que quieres que hagan, y cualquier fallo que cometas al indicarselo se convertirá normalmente en error. Empezando Este tutorial te guiara a través del script por defecto de LSL y hablaremos sobre la estructura básica de un script, como arrancar el script, y como conseguir algunos scripts gratuitos para que practiques con ellos. La primera cosa que necesitas hacer es encontrar un sitio donde puedas crear y renderizar un cubo (u otra forma básica). Si no estas acostumbrado con la construcción o "renderizacion" de un objeto, déjame explicarte brevemente como hacerlo... Para crear un nuevo objeto primitivo ("renderizar un prim"): * Haz click con el botón derecho en el suelo. * Selecciona "Crear" ("Build") en el menú circular. La ventana de edición se abrirá. La forma del cubo esta seleccionada por defecto, * Haz click con el botón izquierdo en el suelo para "renderizar" este prim en el sitio. Siguiente paso: Mientras mantienes tu prim seleccionado, ve a la pestaña "Contenido" ("Contents") en el panel de edición y pulsa el botón "Nuevo Script" ("New Script") para crear un nuevo script. Si no ves la pestaña de "Contenido" en la ventana de edicion, pero ves un botón "Más >>" ("More >>"), pulsa este botón para ver las pestañas. default { state_entry() { llSay(0, "Hello, Avatar!"); } Página 1
tutorial de SLS touch_start(integer total_number) { llSay(0, "Touched."); } } La mayor parte de este tutorial la pasaremos con los conceptos básicos de programación y trabajando sobre la plantilla de este script con el que siempre empiezas cuando creas un nuevo script. Estructura básica de un script El script por defecto está escrito de forma que el objeto dice una frase en cada uno de los dos "eventos" ocurridos. LSL es un lenguaje "orientado a eventos". Cuando un script empieza a ejecutarse, funciona esperando a que sucedan eventos en el mundo que le rodea. Eventos * El término eventos pueden incluir cosas comunes como toques, colisiones, creaciones, colocaciones, escuchas, temporizadores, etc. * Por ejemplo, si alguien toca la puerta de tu casa eso es un evento de "toque"("touch event"). Puedes programar la puerta para que responda haciendo que se abra, o que se cierre si ya estaba abierta. * Si un objeto es golpeado o si él golpea algo, eso es un evento de "colisión"("collision event"). * Los objetos también pueden ser instruidos para "escuchar" el texto de chat, y cuando leen una determinada palabra lanzar un evento para hacer que el objeto responda a ella. Para responder o "manejar"("handle") esos eventos, organizamos nuestros scripts en conjuntos de "manejadores de eventos"("event handlers"). Manejadores de eventos * Los manejadores de eventos son conjuntos de instrucciones que se ejecutan cuando el evento correspondiente ocurre. * Si no quieres responder a cierto tipo de evento, simplemente no incluyas un manejador de eventos para él en el script. * Como puedes ven en la plantilla del script, sólo manejamos dos eventos, "state_entry" y "touch_start" * "state_entry" es un manejador de evento que se invoca cuando el script entra en el estado por defecto, que usualmente sólo sucede la primera vez que el script se ejecuta. Estados * Los manejadores de eventos se agrupan en "estados"("states"). * El tema de los estados está más allá del nivel de este tutorial, así que los explicaré brevemente. * Habitualmente la mayoría de los scripts solo tienen un estado, "default", el estado por "defecto". Algunas veces puedes querer cambiar tu conjunto de manejadores de eventos para responder de forma diferente, en esos casos deberás crear más estados. * No obstante, la mayoría de los scripts funcionan bien sólo con el estado "default". La primera línea de nuestra plantilla de script empieza con la palabra "default". Esta es la etiqueta que define el estado especial por "defecto", que es el estado por el que todos los scripts comienzan. "staty_entry" se encuentra normalmente en la mayoría de los scripts porque es el primer lugar donde colocar (o inicializar) todos tus datos. Sintaxis Antes de empezar por el código linea a linea, deberías conocer que es la "sintaxis" y por qué es importante. Verás por todas partes llaves, paréntesis y distintas palabras, y te estarás preguntando que es todo ese galimatías. Esos símbolos forman parte de la Página 2
tutorial de SLS gramática (los programadores prefieren llamarlo "sintaxis") del lenguaje. LSL tiene una sintaxis parecida a C, Java, PHP, Javascript y otros lenguajes. Los errores de sintaxis son uno de los más frecuentes que la gente comete cuando programa. Afortunadamente son capturados casi siempre por el compilador (el programa que convierte tu código fuente en un programa ejecutable), por eso siempre sabrás cuando cometes un error de sintaxis. Llaves Las "llaves"("curly braces") que ves se usan en LSL para "agrupar" conjuntos de instrucciones o conjuntos de manejadores de eventos. A menudo indico a los que son nuevos en la programación que las llaves "{" y "}" realizan el trabajo de señalizadores que marcan el principio y el fin de un conjunto de instrucciones. Punto y coma Todas las instrucciones en LSL tienen que terminar con un "punto y coma"("semicolon"). Imagina este punto y coma de la misma forma que tú usas un punto para acabar tus frases. El uso de punto y comas hace que el "espacio en blanco" de tu código fuente pierda importancia. Esto permite que tú puedas "disponer" tus instrucciones en una o más líneas y hacer que quede bien formateado. Espacio en blanco Los "espacios en blanco" incluyen cosas como tabulaciones, espacios, retornos de carro, etc. Los espacios en blanco no tienen importancia en la mayoría de los casos, pero se usan para hacer el código fuente más legible. Por ejemplo, la línea llSay(0, "Hello, Avatar!"); también podría ser escrita correctamente así: llSay ( 0, "Hello, Avatar!" ) ; // fijate en los espacios Incluso podrías dividirla en múltiples lineas, p.e.: llSay ( 0, "Hello, Avatar!" ); Esto es por lo que el punto y coma es importante para indicar el fin de la instrucción. Generalmente dividirás tus instrucciones con espacios o retornos de carro, pero cada elemento de la instrucción debe permanecer contiguo (p.e., la palabra "llSay"). Normalmente se indenta el código fuente un nivel por cada conjunto anidado de instrucciones, como veras aquí que cada vez que usemos un conjunto de llaves se indenta un nivel por convención para hacer más fácil la lectura. Cierra lo que abras Finalmente, sobre el tema de la sintaxis, normalmentedeberás tomar nota de cualquier paréntesis, llave o dobles comillas, ya que tendrás que usar el mismo signo para "cerrar" el correspondiente marcador "abierto". Por ejemplo, los paréntesis en llSay() coinciden, la llave que empieza el siguiente nivel en la etiqueta del estado por "defecto" coincide con la última llave en nuestro editor, y las llaves de su interior igualmente coinciden unas con otras. Recorriendo el script por defecto Página 3
tutorial de SLS La primera linea del script declara el estado "default"(por "default"). Por ahora, recuerda simplemente que siempre necesitas un estado llamado "default" en cada script (aunque no tenga por qué estar en la primera linea) y que un estado es donde agruparemos los manejadores de eventos. La segunda línea simplemente abre la llave marcando el inicio del conjunto de manejadores de eventos para el estado "default". La siguiente linea es una etiqueta identificando el manejador de evento "state_entry" para el estado "default". Aqui declararemos que instrucciones se deberán ejecutar cuando el evento "state_entry" se produce. Siguiendo a esta linea hay otra llave abierta, que maca el inicio del conjunto de instrucciones para el manejador de evento "state_entry". En este script, todo es muy simple: sólo tenemos una instrucción para ejecutarse cuando el evento "state_entry" se produce. Si hubiera mas instrucciones, las verías en formato de lista, una por linea, indentadas al mismo nivel que la instrucción llSay(). Funciones llSay() es un tipo de instrucción llamada "funcion". Las funciones es una forma de "pasar el testigo" para completar el trabajo a otro conjunto de instrucciones localizado en otro sitio. Cualquier función que aparece de color rojo en tu editor de scripts y que empieza con dos L minúsculas es una función "propia" de LSL. Las funciones propias son funciones que siempre tenemos disponibles en todos nuestros scripts, y que están preparadas para cuando las necesitemos. La mayoría de las funciones propias nos permiten ordenar al servidor controlando la región que realice alguna acción sobre nuestro entorno o para conseguir datos de este entorno. Puedes conseguir una guía de todas esas funciones propias simplemente pulsando el menú "Ayuda"("Help") que usando tu navegador te mostrará un documento de tu disco duro con dichas funciones. Desde el mismo menú puedes acceder a un navegador interno que te mostrará el wiki sobre LSL de Second Life. Además de las funciones propias, puedes crear tus propias funciones "globales", que son una forma fácil de poner el código redundante en un único lugar que puedas utilizar desde diferentes sitios en tu script. Específicamente, la función llSay() es una de las pocas funciones propias que invocarás para hacer que tu objeto "hable" en un canal. Para que las funciones hagan algo útil, les tendrás que dar alguna información (datos) para ejecutar la acción que van a realizar. Muchas funciones también retornan algún dato como resultado de la acción (o cálculo) que han realizado. Imagina que eso es como cuando rellenas un formulario en un navegador en un sitio web. Rellenas el formulario con algunos datos, lo envías y consigues un resultado (una nueva página web). Nota: no todas las funciones necesitan datos para hacer su trabajo, y no todas las funciones devuelven un resultado. Los datos que una función requiere se llaman normalmente "parámetros", y son colocados dentro de los paréntesis. Cada parámetro se separa por comas, y el orden en que son escritos es importante. No puedes escribirlos en cualquier orden, porque el código que maneja la función los espera en un orden determinado. Página 4
tutorial de SLS Por ejemplo, llSay() necesita dos parámetros. El primero es el numero de canal. El segundo es una cadena("string"), el texto que quieres que el objeto diga. Una "cadena" es un carácter, palabra o frase de texto. Imagina una cadena como un grupo de letras, números, espacios, símbolos de puntuación, o básicamente todo lo que puedas escribir. En LSL, todas las cadenas se colocan entre dobles comillas, y normalmente se ven en verde en el código fuente si todo esta funcionando correctamente. Si te estas preguntando como puedes utilizar las dobles comillas como parte de tu cadena, puedes hacerlo precediendo cada doble comilla con una "contrabarra"("backslash"), de esta forma: \" Y desde que \ es un carácter especial para hacer esto, si quieres usarlo a su vez en el texto, has de ponerlo dos veces en ese caso. De esa forma, tienes que poner dos contrabarras por cada una que quieras que aparezca, es decir: \\ Una forma de que te des cuenta de que has olvidado usar propiamente las dobles comillas es que el color verde del texto afecta al resto de tu script. No es un problema realmente, por que el compilador capturara el error antes de convertir tu script en un programa ejecutable. La función llSay() El primer parámetro de llSay() es el numero del canal por donde el objeto hablará. El segundo parámetro es el texto que queremos que el objeto diga. Hay mas de cuatro mil millones de canales de comunicación en Second Life. No obstante hay un numero de canal "especial", y es el canal 0 (cero). El canal cero es el canal por el que hablamos con los demás en el chat local. Todos los demás canales son invisibles para nosotros, no podemos escuchar nada de ellos sin usar un objeto programado que lo haga por nosotros (si es posible escribir en estos canales, usando el formato /numero_canal) Además de hablar por estos canales, cualquier objeto puede ser programado para "escuchar" ("listen") en uno o más canales. Esto facilita un medio para que objetos separados puedan comunicarse unos con otros sin interferir nuestro canal de chat: simplemente selecciona un numero aleatorio distinto de cero y haz que tus objetos se comuniquen a través de ese canal. llSay es solo una de las pocas funciones que pueden hablar en el chat local: * La función llSay() habla en el canal especificado hasta un radio de 20 metros. * llWhisper() hace la misma función, pero solo en un radio de 10 metros. * llShout() es otra de estas funciones, y tiene un radio de 100 metros. Estas tres funciones tienen efecto incluso a través de las separaciones entre regiones. De vuelta a nuestro script Detrás de la función llSay(), finalizamos el conjunto de instrucciones para "state_entry" cerrando llaves con '}'. Tras esto, definiremos que hacer en el manejador de evento "touch_start". Al contrario que el manejador de evento "state_entry", "touch_start" recibe una serie de datos del sistema cuando el evento sucede. Se trata de lo que ves entre paréntesis, "integer total_number". Nota: si te estas preguntando se hace con los datos cuando tu invocas una función, esto es lo que sucede desde el otro lado. Los manejadores de eventos no Página 5
tutorial de SLS se deben confundir con funciones, pero reciben datos de la misma forma que las funciones. El dato que se envía a un manejador de evento es alguna cosa útil que esta asociada con el evento. Por ejemplo, el manejador de evento que se ejecuta cuando un objeto esta "escuchando" en un canal recibe cuatro datos cada vez que alguien dice algo: * * * *
El numero de canal El nombre de la persona u objeto que dice el texto. Una "clave"("key") única del avatar u objeto que dice el texto, y El texto.
En el manejador de evento "touch_start" recibimos un numero que nos dice cuanta gente esta tocando el objeto. A menos que más de una persona este tocando el objeto a la vez, el número enviado va a ser siempre 1 para este manejador de evento. Puede que te estés preguntando que significa la palabra "integer". Déjame que te explique brevemente las variables. Variables Como hemos visto, "touch_start" recibe una variable "integer"("entera") llamada total_number. Si conoces Algebra, estarás familiarizado con el termino "variable". En programación las variables funcionan de una forma similar. Las variables son "contenedores" para datos, a los que asignamos una etiqueta. Por ejemplo aqui, la etiqueta dada a este numero es "total_number". Las variables pueden alojar diferentes tipos de datos. Cada tipo de datos utiliza su propio tipo de variable: * integer (entero): todos los números enteros (no decimales). * float (flotante): para números que contienen valores decimales. En el caso que no necesites obligatoriamente una variable flotante, es preferible usar una entera, debido a que exigen más recursos. * string (cadena): utilizado para almacenar texto * vector: este tipo guarda tres valores flotantes, y se usa típicamente en ocasiones donde un trío de números flotantes es necesario para guardar datos agrupados (por ejemplo, las coordenadas x,y,z) * rotation (rotacional): este tipo guarda un complejo conjunto de datos utilizados para realizar rotaciones, conocido como cuaternión. Se trata probablemente del tipo de datos menos intuitivo, ya que la mayoría de la gente no está familiarizada con los cuaterniones, y menos todavía con el sistema de Euler para especificar una rotación. Los cuaterniones son muy eficientes matemáticamente si sabes como manejarlos, pero puedes encontrar varias funciones propias de LSL de conversión para rotaciones de Euler si no es el caso. * key (clave): este tipo de datos parece una cadena, pero se usa específicamente para mantener un valor que identifica unívocamente cada objeto en SL (al estilo de un numero de carnet de identidad). * list (lista): mantiene una lista compuesta referenciada por indices de cualquiera de los tipos antes citados, y que permite crear de forma dinámica más espacio para datos mientras el script esta en ejecución. Si todo esto suena complicado, simplemente recuerda que una "variable" es una etiqueta y que es el contenedor de algún dato. En cada sitio donde tu pongas esta etiqueta, el numero, cadena o dato que almacena sera utilizado en su lugar. De vuelta al script otra vez Página 6
tutorial de SLS En nuestra plantilla de script, obtenemos una variable en "touch_start", pero para los propósitos de este script nunca la usaremos desde que no es necesario saber cuanta gente esta tocando nuestro objeto al mismo tiempo. Incluso si no usamos una variable que se nos suministre, debemos definir el "prototipo" del manejador del evento correctamente, por lo que "integer total_number" debe estar presente. Las funciones lo hacen de la misma manera. Cada parámetro debe ser indicado, se necesite o no, y como he dicho antes, los parámetros han de estar en un orden especifico, de forma que coincidan con el "prototipo". Pude parecer exagerado, pero ayuda al compilador a saber que estas intentado hacer si todo es consistente. De cualquier forma, finalmente "touch_start" llama a una función llSay() que dice una frase diferente en el canal 0. Cerramos el script con dos llaves consecutivas de cierre. La primera cierra el manejador de evento "touch_start", y la segunda cierra el estado "default". Compilando Compilar un script es el proceso de coger las instrucciones que has escrito y convertirlas en código maquina que los ordenadores pueden entender. Si no lo has hecho ya, cambia sin problemas las cadenas de texto, y entonces pulsa el botón "Guardar"("Save") en la esquina inferior derecha para guardar tu script. Una ver pulses el botón, tu script será chequeado sobre posibles errores simples de gramática, luego sera compilado y finalmente sera subido al servidor SL. Si se encuentra un error, se te informara sobre que tipo de error es y en que linea se ha producido. Si te sale algún error compilando este script, simplemente empieza con uno nuevo, ya que en este caso se trata del script por defecto. Una vez pulsas el botón, si tienes la casilla "Ejecutando"("Running") marcada, empezaran a ejecutarse las instrucciones inmediatamente, lo que significa: * Entrara en el estado "default". * Ejecutara las instrucciones del manejador de evento "state_entry()" si existe. * Esperara que ocurran nuevos eventos. El editor de scripts Echaremos un vistazo a las características del editor de scripts. Si desmarcas la casilla de "Ejecuntado"("Running") en la esquina inferior izquierda de tu ventana del editor de scripts, se detendrá tu script y lo situara en "animación suspendida". Cuando vuelves a marcar esta casilla, se reanudara la ejecución desde donde se detuvo. Desmarcar la casilla "Ejecutando"("Running") es una buena manera de detener tu script si se esta ejecutando erróneamente (por ejemplo, causando spam). El botón de "Reset" detendrá cualquier actividad que tu script esté haciendo, borrará todos los datos almacenados y reiniciara tu script a su estado original. Básicamente, vuelve a ejecutar el script desde cero. En la esquina inferior izquierda de tu editor de scripts, hay un combo desplegable que dice "Insert..." Se trata de una referencia rápida a todas las funciones propias de LSL, constantes, manejadores de eventos, etc. Todo que es propio del LSL se puede Página 7
tutorial de SLS encontrar aquí. Notarás que la ventana de tu editor de scripts tiene cosas en diferentes colores, este "remarque de la sintaxis" ayuda a identificar las distintas partes en tu script. Cada color del remarque de sintaxis representa un elemento estructural específico para el script. Las funciones propias se muestran en rojo, las cadenas y palabras reservadas en verde, y las etiquetas de los manejadores de eventos están en azul claro. Truco: cualquier cosa que tenga un color es algo sobre lo que puedes pasar la flecha del ratón y conseguir una pequeña ventana de ayuda. Esto viene bien cuando necesitas recordar rápidamente que parámetros son necesarios para una función (es decir, su prototipo), o una breve explicación sobre que hace o significa una función propia o una palabra clave, o cualquier nota sobre ella. Finalmente, en el menú hay mas opciones de edición y la posibilidad de restaurar el código de tu script a como estaba la última vez que lo guardaste. Precaución: Ten cuidado con esta opción. No es simplemente un deshacer la última acción como en la mayoría de los editores de texto (el Ctrl+Z). En este caso se descartaran todos los cambios realizados desde la última vez que lo guardaste. Si durante una operación de salvar obtienes un error del compilador, aparecerá en ía parte inferior del editor. Si haces doble click en la linea que describe el error, deberia mover el cursor en la parte superior del editor a donde se ha producido el error. Esto es todo lo que hay sobre la ventana del editor de scripts. Moviendo Scripts dentro y fuera de objetos Cada objeto en SL tiene su propio mini inventario. Los objetos pueden contener cualquier otro objeto de inventario en su propio inventario. La forma en que dotamos de programación a un objeto es añadiendo un script al contenido de ese objeto. Si ya tienes un script en un objeto y lo quieres guardar en tu inventario principal (de forma que lo puedas usar en otros objetos), debes editar el objeto, ir a la ventana de edición, abrir la pestaña de contenidos, encontrar tu script en la lista, y arrastrarlo a tu inventario. Normalmente los colocaras en la carpeta "Scripts" de tu inventario. Puedes guardar un script donde quieras de tu inventario, pero es mejor mantenerlos todos en un lugar para que permanezca organizado. Para colocar un script en un objeto desde tu inventario, haz lo mismo pero al revés. Selecciona el script de tu inventario y arrástralo a la carpeta de contenido del objeto. Alternativamente, puedes arrastrar y soltar un script desde tu carpeta a la superficie del modelo 3D de tu objeto, y se copiará a su contenido automáticamente. Cuando añadas un script a un objeto, el script empezará a ejecutarse, a menos que la casilla "Ejecutando"("Running") esté desmarcada. Scripts gratuitos Para acabar, déjame mencionar un buen lugar para obtener scripts. Los foros de Second Life incluyen un foro especial llamado "Script Library" que contiene scripts que la gente ha donado gratuitamente para que cualquiera los use. Pásate por ese foro y consigue algún script y juega con el. Son un gran método para aprender mas sobre el lenguaje. Puedes copiar y pegar el script desde tu navegador web a tu editor de scripts. Página 8
tutorial de SLS Asegúrate de establecer acuerdos con el autor original sui tu usas su trabajo, o un derivado en un objeto que tu vendas. La gente podría enfadarse si te beneficias de su trabajo sin su permiso. Para que empieces, aquí tienes un par de referencias que pueden ayudarte en tus inicios: * Paquete de bienvenida * Cubo de color aleatorio El "Paquete de bienvenida" ("Good Neighbor Package") contiene algunos pequeños scripts que hacen cosas simples como que un objeto rote o que el objeto desaparezca tras un intervalo de tiempo. El "Cubo de color aleatorio" ("Random Color Cube") contiene un script de ejemplo que demuestra varios aspectos comúnmente usados en LSL, incluyendo variables, funciones globales, un temporizador, mensajes instantáneos, claves y otras cosas divertidas. Un buen "siguiente paso" para realizar más allá del script por defecto que se ha visto en este tutorial es analizar estos scripts y hacerse una idea de que están haciendo. El Wiki de LSL Una gran referencia sobre LSL está disponible en la web en el portal LSL de Second Life. No puedo dejar de elogiar este recurso. Es definitivamente la fuente principal de información sobre el Lenguaje de Programación de Linden. Todo sobre el lenguaje se encuentra allí, en un bien documentado y frecuentemente actualizado conjunto de paginas, donde cualquiera es libre de corregir, revisar o añadir sus propias notas sobre el lenguaje y su API. Conclusión Este tutorial pretendía darte una visión básica del LSL, un recorrido del script por defecto, e indicarte algunas direcciones donde aprender más. Espero que hayas sido capaz de aprenderlo suficiente para arrancar, y que estés en el camino de crear mas riqueza para SL. Si necesitas ayuda con un script, por favor usa los siguientes recursos: * El portal de LSL de Second Life. * Los foros de Second Life (al menos hay dos foros de programación allí) * La ayuda en línea (menú "Ayuda"("Help")) Licencia Este texto e distribuido segu´n la licencia Creative Commons Attribution-NoDerivs License.
Página 9