糟糕的 Linden Scripting Language

1236681319|%Y-%m-%d|agohover

Linden Scripting Language(LSL) 是用在網路虛擬世界 Second Life 所使用的 scripting language。Second Life 在國內雖然完全不紅,但在國外倒是有頗多社群。由於 Second Life 允許網路居民們自行創造物件,並使用 LSL 來操縱物件的行為,再加上大家皆可自由買賣或匯兌貨幣 (SL 中的貨幣單位是 L$,一美金大約可兌換 L$260 上下),可說是把 Web2.0 精神搬到線上遊戲的絕佳範例。

最近因為工作的關係,一直在寫 LSL 程式。然而因為 LSL 有些地方設計不佳,一旦功能愈來愈複雜,programmer 的痛苦程度也是指數成長,不得不吐吐苦水。

Strongly-Typed

很奇怪的是,LSL 是一種強型別的語言。這年頭設計易於快速開發的 scripting language 幾乎沒人在用強型別,除非是很在意效能,不過 LSL 還是慢得要命。雖然轉型只要用 C 式的語法即可,但多打這些字就會讓人很不爽。

大多的強型別語言都會要求變數需要宣告,LSL也不例外。不過 LSL 是我看過第一個不能一次宣告多個同型變數的語言:

integer i, j; // 很好笑的 syntax error

難用的陣列

LSL 中的陣列稱之為 list,使用 list 大概是 LSL 中最痛苦的一件事。LSL 雖然是強型別,偏偏它的 list 是可以容納不同型別的容器,所以只要取用 list 中的元素,就一定要轉型:

list a = [1024, "Hello World"];
integer a0 = llList2Integer(a, 0); // 得到 1024
string a1 = llList2String(a, 1); // 得到 "Hello World"

也許你會問,怎麼不用 integer a0 = (integer)a[0] 的寫法,雖然還是麻煩,但總比上面又臭又長的函式短得多。答案會讓你笑到肚子痛:LSL 沒有 a[i] 的寫法!所以要寫入某個元素時該怎麼辦呢?以下是一個寫法:

a = llListReplaceList(a, [new_item], i, i); // 相當於 a[i] = new_item;

光看就覺得慢到爆炸。

無自訂資料結構

這年頭連 assembler 都提供 struct 的功能,讓 programmer 遇到複雜的資料也不致於感到絕望,但不幸的是 LSL 不提供 struct。好吧,許多 scripting language 都用 hash table 來代替 struct,那麼 LSL 有沒有 hash table 呢?抱歉,沒有。

所有你能用的,就是上面那個難用到死的 list。喔對了,list 是一維的,如果你想在 list 中塞入 list,則內部的 list 會自動被展開:

list a = [1, 2, 3];
list b = ["hello", a, "world"]; // b 會變成 ["hello", 1, 2, 3, "world"]

programmer 的苦難結束了嗎?還沒。

封裝不佳的 state 設計

LSL 並不是傳統的 procedural language,而是使用 state 及 event 來控制程式的流程。以下是一個範例:

default
{
    state_entry()
    {
        llSetColor(<0.0, 0.0, 0.0>, ALL_SIDES);
    }
    touch_start(integer num)
    {
        state on;
    }
}

state on
{
    state_entry()
    {
        llSetColor(<1.0, 1.0, 1.0>, ALL_SIDES);
    }
    touch_start(integer num)
    {
        state default;
    }
}

這例子展示的是顆電燈泡,它有兩個 state:default 和 on,被使用者點選時,會在這兩個 state 之間轉換,並設定自己的顏色。state 的設計很適合 Second Life 本身的應用,畢竟在設計互動物件時,programmer 最先在腦中成形的就是 state machine。

然而 state 中只能宣告該 state 所有的 event handler,而不能宣告 state 專屬的變數或函式,所有的變數和函式都必須宣告在全域空間中。只要打開 script 檔案看到開頭一排的全域變數,一整天的心情都會變很差。

你以為 LSL 好心到提供 const 幫你檢查你是否覆寫自己宣告的常數嗎?不好意思,你要為自己的白痴行為負責了。

不提供 library/module

壓死駱駝的最後一根稻草,乖乖的 copy-paste 吧!當然,出現 bug 時,你要為自己的白痴行為負責。


Comments

Add a New Comment
or Sign in as Wikidot user
(will not be published)
- +
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License