惡靈勢力2 腳本
惡靈勢力2 腳本 是可以在遊戲中的虛擬機器裡被運行的伺服器端的腳本。它們使用Squirrel 語言編寫, 這是一種類似於Lua的腳本編譯語言.
這條內容由Dazai Nerau譯自英文版頁面. 歡迎任何人補充新內容或者修改其中的錯誤.
用途
導演腳本
VScripts 在惡靈勢力2中的最通常的用處是用來指揮人工智慧導演系統。 這些腳本的用途包括但不限於調整普通感染者的數量或者禁止BOSS感染者的產生 , 或者用以自訂諸如onslaughts和gauntlets之類的遊戲事件, 甚至是複雜的屍潮事件和完全定制的
自訂結局 。 大多數官方活動也是通過這種方式製作的。導演腳本的主要工作是將導演系統所使用的各種變數的值覆蓋寫入DirectorOptions
表.
一次只能運行一個導演腳本。執行新的導演腳本將終止先前運行的任何腳本並刪除它在DirectorOptions
表中設置的任何值。
實體腳本
另一個常見的用途是將腳本附加到實體上。 腳本提供了輕鬆便捷的途徑以修改或讀取大多數實體的屬性,甚至可以寫入新的KeyValues(鍵值) 。這便使得在Hammer中不可能實現的對實體I/O系統的複雜控制成為了可能。
任何實體都能運行腳本,並且擁有以0.1秒運行一次think函式的能力,也可以將腳本代碼作為實體輸出以執行.
一些實體還擁有VScripts的專用功能,最顯著的例子是point_script_use_target ,它能將其他實體轉換為完全可程式設計的定時按鈕。
全域腳本
腳本也可以被設定成在地圖載入時執行,基於特定的遊戲模式或者可選的地圖名。 這些腳本通常用於為突變模式 創造劇本或者修改全域導演系統設置,當然也可以用於對地圖的自訂。
全域腳本可以添加腳本鉤子函式,這些函式會在遊戲中的特定時間發生時被呼叫,比如當玩家/物件造成傷害。
這些腳本有許多實用功能和功能,包括資源和建造系統,以及產生自訂屍潮。請閱讀EMS教程 瞭解詳情。
其他用途
總而言之,這些腳本擁有各種各樣的超能力,包括從預編譯的清單中或者程式性地產生實體 ,產生感染者 ,自訂一個 HUD系統 ,
跨關卡地存儲資料 至硬碟,以及其他數不勝數的功能。
請閱讀惡靈勢力2 Vscript 範例 瞭解詳情。
指令檔
腳本以文字檔的形式被讀取, 腳本的副檔名為.nut
和 .nuc
, 其中 .nuc
是對純文字形式的 .nut
的加密. 自訂腳本會從 \left 4 dead 2\left4dead2\scripts\vscripts\中被讀取, 包括.vpk檔中的也是這樣。
位置
- 官方的 .nuc 指令檔位元於 scripts/vscripts
- left 4 dead 2\left4dead2\pak01_dir.vpk
- left 4 dead 2\left4dead2_dlc1\pak01_dir.vpk
- April 22, 2010 The Passing update
- left 4 dead 2\left4dead2_dlc2\pak01_dir.vpk
- October 5, 2010 The Sacrifice update
- left 4 dead 2\left4dead2_dlc3\pak01_dir.vpk
- March 22, 2011 Cold Stream Beta / L4D1 Transition Project update
- left 4 dead 2\update\pak01_dir.vpk
- This is where mutations were updated/replaced bi-weekly.
- left 4 dead 2\sdk_content\scripting\scripts\vscripts\
- Plaintext versions of many of the scripts introduced in the EMS update.
解密NUC文件
.nuc 檔是經過ICE加密的 .nut 文件. 其秘鑰是 SDhfi878. 你可以使用 VICE 對它們進行解碼.
Packages with deciphered official scripts are also available.
載入腳本
VScripts以不同的方式載入,具體取決於它們的用途. 它們也可以通過在控制台手動輸入script filename
的方式載入.
導演腳本
- 使用info_director 實體進行如下輸入(inputs)
BeginScript <script name>
- 執行一個普通的導演腳本, 比如為了onslaught事件而設計的腳本.
EndScript
- 中止執行腳本並重置導演系統設置中的變數值.
BeginScriptedPanicEvent <script name>
- 執行一次腳本化的屍潮
![Note.png](/w/images/thumb/c/cc/Note.png/10px-Note.png)
BeginScriptedPanicEvent
一起使用的腳本將無法工作,即使你能在其他腳本的背景關係中使用子目錄. 它們必須位於vscripts資料夾下,否則它們只會簡單地以1個階段1秒的延遲運作.導演腳本(結局)
<map name>_finale.nut
會在結局地圖載入時被自動讀取. 這個腳本也可以因trigger_finale 的使用而被觸發, 或者通過玩家手動觸發, 或者通過ForceFinaleStart
這一輸入觸發.- 要做到: trigger_finale 還有一個指定結局腳本的選項,但它似乎不起作用.
所有的導演腳本存在於DirectorScript
這一腳本域(script scope)之中.
實體腳本
- 方式1:地圖載入時自動讀取
- 通過設置實體中的Entity Scripts鍵值載入腳本
- 方式2:手動載入
- 使用
RunScriptFile
這一輸入
實體腳本位於_<unique ID>_<entity name>
這一腳本域中
全域腳本
- 方式1:通過模式指定腳本
- 與遊戲模式 同名的腳本將會自動運行. 比如運行一個地圖
map <map name> mutation12
將會自動載入mutation12.nuc
這一寫實對抗腳本. - 全域腳本位於
g_ModeScript
這一腳本域中
![Note.png](/w/images/thumb/c/cc/Note.png/10px-Note.png)
- 方式2:通過地圖指定腳本(只在腳本化模式中有效)
- 每個地圖的腳本可以被在當地圖運行指定模式時被創建和執行, 使用
<map name>_<mode name>.nut
這一格式的指令, 比如,c1m4_atrium_mutation12.nut
. - 它們位於
g_MapScript
這一腳本域中
腳本環境
請閱讀含有類別(classes)和函式(functions)的L4D2腳本函式清單 以瞭解詳情.
當一個腳本被載入,它會被放入一個表,我們稱之為腳本域(Script Scope).模式、地圖和導演腳本會被放入設置域中,同時會為每個實體腳本生成獨一無二的域. 有關更多資訊,請參閱Vscript的基本原理 .
表的結構
DirectorScript = // Base Director Scope.
{
DirectorOptions // Base DirectorOptions table.
MapScript = // Map Script scope.
{
BaseScriptedDOTable // Hardcoded DirectorOptions.
ChallengeScript = // Mode Script scope.
{
MutationState // Initial values for SessionState.
MutationOptions // Initial values for SessionOptions.
}
LocalScript = // Script Scope Director Scripts are placed in.
{
DirectorOptions // DirectorOptions for current Director Script (like onslaughts). Only availabe when a script is active.
}
MapOptions // Initial values for SessionOptions.
MapState // Initial values for SessionState.
}
}
g_MapScript // Global reference to the Map Script scope (DirectorScript.MapScript).
g_ModeScript // Global reference to the Mode Script scope (DirectorScript.MapScript.ChallengeScript).
g_rr // Scope holding the Response Rule system.
g_RoundState // TODO
SessionOptions //Global Director options (Scripted mode only).
SessionState //State variables for game modes (Scripted mode only).
委託
一些表已經設置了委託, 所以如果一個鍵值空缺, 就會從其父表中讀取該值.
表的委託長成這樣:(右邊是父表)
- The Director Scope
(DirectorScript.MapScript.ChallengeScript; DirectorScript.MapScript.LocalScript) < DirectorScript.MapScript < DirectorScript < ::
- DirectorOptions
DirectorScript.MapScript.LocalScript.DirectorOptions (When Director Script active) < DirectorScript.MapScript.ChallengeScript.DirectorOptions (Scripted mode only) < DirectorScript.DirectorOptions
實體腳本
腳本域為 _<unique ID>_<entity name>
把一個腳本添加到一個伺服器端的實體的Entity Scripts的鍵值中可以將其以實體腳本載入. 腳本會在實體產生時被執行,並載入到一個唯一的腳本域內,該範圍由唯一識別碼後跟實體名稱或種類名組成.
Think函式可以在 thinkfunction
鍵值 中設置, 指定的腳本函式會以0.1秒一次的頻率被執行. 函式也可以通過I/O系統以RunScriptCode function_name(argument, ...)
的形式手動呼叫.
實體腳本能夠通過self
引用到呼叫它們的實體,這使得腳本可以輕鬆地通過它的類別方法(class methods)控制實體. 有些實體類別還有可用的鉤子函式(hook functions). 各種方法和鉤子都可以在這裡找到.
一些實體擁有額外的叫本宮拿:
- point_script_use_target - 能通過方法或者鉤子來控制按鈕.
- logic_script - 能夠一個一個叫做
EntityGroup
的陣列傳遞過個實體的名字給腳本. - point_template
- env_entity_maker
- info_item_position
可以使用控制台命令ent_fire <name of entity> runscriptfile <relative vscript path>
重新載入腳本. 這樣做方便快捷,非常有用.
I/O系統 相互作用
任何腳本可以通過使用EntFire()
and DoEntFire()
來觸發地圖實體的輸出. 由於activator
和 caller
聲明在 DoEntFire()
中是控制碼, 所以可以直接通過 "!self" or "!activator" 關鍵字來觸發實體, 即便你不知道它們的名字, 只要實體的控制碼是有效的.
EntFire( "church_bell_relay", "Trigger", 0 ); // Fires an output to the Trigger input of the named entity.
player <- null;
while(player = Entities.FindByClassname(player, "player")) // Iterate through the script handles of the players.
{
DoEntFire("!self", "speakresponseconcept", "PlayerLaugh", 0, null, player); // Make each player laugh.
}
相反, CBaseEntity::ConnectOutput()
和 DisconnectOutput()
可以被用來在指定的實體輸出被觸發時呼叫腳本函式. 值得一提, 可以從I/O系統中運行任意的VScript代碼,通過使用 RunScriptCode
對所有的實體(但少數實體並不支援這麼做)進行輸入. 那些代碼會在該實體的腳本域中被執行.
![Warning.png](/w/images/thumb/c/cb/Warning.png/10px-Warning.png)
RunScriptCode
傳遞字串.全域腳本
使用遊戲模式命名指令檔,命名特定於模式的腳本,並在每次以指定模式載入地圖時執行該指令檔。 如果存在模式腳本,則還可以載入具有地圖名稱後跟底線和模式名稱的地圖特定腳本。
腳本化模式
添加模式腳本將為遊戲模式啟用腳本化模式。 這對於遊戲中包含的基本遊戲模式也同樣生效。
腳本化模式將實用程式功能載入到g_ModeScript
域中, 禁用導演設置的MaxSpecials
“2” 選項, 啟用 遊戲事件回呼 和 腳本鉤子函式. 它似乎破壞了黑暗狂歡節最後的坦克音樂.
共用表
SessionState
- A table for storing session specific variables. Not preserved across level transitions.
SessionOptions
- Base Director Options for the game mode.
可用函式
模式腳本
Use script scope g_ModeScript
表
MutationState
- Initial values for the
SessionState
table. MutationOptions
- Initial values for the
SessionOptions
table.
地圖腳本
Use script scope g_MapScript
表
MapState
- Map specific values for the
SessionState
table. MapOptions
- Map specific values for the
SessionOptions
table.
術語
- 導演設置(DirectorOptions)
- 一個控制人工智慧導演系統的行為的由命名變數組成的表。
- 實體控制碼(Entity handle)
- 也被稱為EHANDLE. 要做到: 類似一種指向實體的指標.
- 腳本控制碼(Script handle)
- 具有C++實體物件的訪問器和更改器的實體實例. 也叫HScript.
- 腳本域(Script scope)
- 存放一個VScript的變數、函式和類別的表.
導演設置
請閱讀L4D2導演腳本瞭解詳情.
協力廠商工具
VSLib
VSLib (VScript Library) 是一個簡單的,羽量級的L4D2的VScript的編譯系統的庫. 它通過為您處理大量繁瑣的工作,大大簡化了VScripts的編碼. 它被用於幾個流行的MOD比如Rayman1103's Admin System 和Stranded. 更多詳情請閱VSLib .
推薦閱讀
- L4D2 Vscript 範例
- L4D2腳本函式清單
- 擴展突變系統(Extended Mutation System, EMS)
- L4D2關卡設計/BOSS感染者禁用
- L4D2工具升級
- 突變模式(L4D2)
- trigger_finale
- info_director
- logic_script
- vscripts
- VSLib
外部連結
- Alternative Tool
- Alternative Documentation
- Director Scripts - .nuc files (Steam forums)
- It's the vscript'ing documentation FAQ! (Steam forums)
- Tutorial - Writing a Mini Game - Tic Tac Toe - Part One (Steam Forums)
- Writing a Mini Game - Tic Tac Toe - Part One - Author's Website
- l4d2 - Vscript example - Tic-Tac-Toe - Video of early Prototype
- l4d2 - Vscript example - Tic-Tac-Toe - updated - Video of current version with "brutally misanthropic AI"
- Mutation scripts (Steam forums)
- Squirrel Binary for Windows
- Squirrel (programming language) - Wikipedia Article on Squirrel
Squirrel: The Programming Language - Documentation and Sample Code
- The AI Systems of Left 4 Dead by Michael Booth (PDF)
"Creating a "Money"/Point System" - Swarm Armory
- Deciphered Official Scripts