LSLとは
マイナー言語 Advent Calendar 2014飛び入り参加させて頂きます。
ご紹介いたしますのはLSLことLinden Script Language。Lindenとは仮想世界サービスSecondLife内を運営する会社。セカンドライフ上で動作し、仮想世界内の事物を操作するスクリプトです。
はいそこ、「セカンドライフってまだあったのか」とか言わない。
Linden Script Language
どうやって書くか
仮想空間内の建築やアクセサリなどは形をもったオブジェクトとして生成されており、オブジェクトはその内部にさらに別のオブジェクトやテクスチャなどのコンテンツを持つ事ができます。スクリプトもこのコンテンツの一つとして作成します。オブジェクトの編集画面でコンテンツリストを開き、New Scriptというボタンを押すとリスト内にスクリプトファイルが作成され、編集画面が開くのでそこに書いていきます。
IDEとかないのん?
専用エディタ、EclipseやVim,Emacsのプラグイン、秀丸のハイライトファイルとかありますが、結局のところ仮想世界内にしかコンパイラがないので最終的には上記の編集画面にコピペして動かすことになります。
どうやって実行するか
スクリプトは保存と同時にコンパイルされ、エラーがなければサーバにバイトコードとして格納されます。この時、編集画面の「Running」にチェックが入っていればサーバのスクリプトエンジン上で即実行を開始します。
なお、サーバのスクリプトエンジン(VM)は、以前はリンデン社が独自開発していましたが、現在はMonoが採用されています。
何ができるか
オブジェクトのパラメータ操作
オブジェクトの色や形、表面テクスチャ、位置や回転などのパラメータを操作します。
例:
クリックされると90度回転して開くドア
波のうねりを表現した水面のアニメーションテクスチャ
チャット
チャットのリスナーを定義することで、アバターがチャット(発言)した内容を検出できます。チャットはアバター同士のオープンな会話の他、チャットチャンネルを指定することでチャットウィンドウには内容を表示せずに発言できるため、オブジェクト同士の通信やアバターからオブジェクトへのコマンドのチャンネルとして使用することもできます。
情報検出
スクリプトが格納されたオブジェクトを基準に、周囲のアバターやオブジェクトの存在や衝突を検出できます。
例:
アバターが乗るとその先のドアが開く自動ドアマット
周囲のアバター名をリスト表示するレーダー
パーティクル発生
クライアントの画面上にパーティクル効果を発生させることができます。パーティクルは豊富なパラメータによって色や形状、動きを定義することができます。
例:打ち上げ花火
物理演算
オブジェクトには物理演算を適用することもできます。物理演算が有効なオブジェクトでは、スクリプトによって物理演算の各種パラメータを取得・設定することができます。
例:ピッチングマシーン
乗り物
オブジェクトをユーザが操作する乗り物として動作・制御させるためのビルトイン関数群が豊富に定義されており、これらを使うことにより気球からバイクまでさまざまな挙動の乗り物を作成することができます。
メディア操作
オブジェクトのある空間に対して権限をもったオーナーであれば、外部サーバに存在する音楽や動画をストリーミング配信することができます。
また、スクリプトと同じオブジェクトに格納された短時間のWavファイルであれば、空間オーナーでなくても(スクリプト実行が許可されていれば)自由に再生することができます。
アバターアニメーション
指定したアバターに任意のポーズをとらせたりアニメーションを実行させたりすることができます(ただし実行開始時にそのアバターに対して許可を求めるダイアログが表示され、そのアバターが許可した場合に限ります)
ポーズやアニメーションは、事前にMMDライクなフリーツールを使ってbvhファイルとして作成し、サーバにアップロードしたものをオブジェクトに格納して指定します。
文法的なこと
ステートとイベント
スクリプトの実行中は常に1つのステートにおかれています。スクリプトの開始と同時にdefaultステートが開始され、以降はstate命令を書くことでユーザが定義したステートに切り替えることができます。
各ステートはそれぞれ開始時/終了時、オブジェクトが生成された時、ユーザにクリックされた時などのイベントハンドラを持ち、スクリプトの挙動は全てこれらに紐付けられたイベントプロシージャ内に記述してゆきます。
型
数値はintegerとfloat、文字列はstringに加えてUUID形式の文字列を扱うことに特化したkey型。
UUIDだけ特別扱いなのは、仮想空間内のオブジェクトやアバターは全てUUIDを振られており、これによって識別するためです。
さらに物体の座標を扱うvector、同じく回転を扱うrotation、配列的なデータを扱うlist(ただしインデクサ的な書き方はできず、要素を取り出すのに型別に定義された関数を使う)の計7種類の型があります。
制御構文
条件分岐はまあ普通にifとelse。switch-caseはなし。ループはforとwhile。foreachもなし。その他、ラベル指定のjump命令と関数からのreturn、加えて前述のステートを切り替えるためのstate文があります。ラベルは先頭に@をつけて表現します。
ビルトイン関数
llSayなど、プレフィックス"ll"をつけた名称の関数が、ビルトイン関数として定義されています。一部の数値・時間計算用の関数を除いて、ほとんどが仮想世界内の情報を扱う関数です。
注意
前述のように、スクリプトは全て仮想空間をホストするサーバのスクリプトエンジン上で実行されます。したがって負荷の高いスクリプトが多く存在するサーバでは、空間のレンダリングやアバターの動作にも影響が出ます(いわゆる「重くなる」)。
そのためスクリプトの記述には、極力負荷を軽減することが求められます。