這一章的目標(biāo)是介紹Mod基本結(jié)構(gòu)葵姥,讓你能夠更好地組織代碼和各種靜態(tài)資源罕模。
饑荒Mod采用了隔離良好的設(shè)計(jì)祭犯,每個(gè)Mod擁有自己的運(yùn)行環(huán)境墓懂,獨(dú)立于游戲主環(huán)境和其它Mod的運(yùn)行環(huán)境。而且單個(gè)Mod的文件結(jié)構(gòu)七蜘,和游戲本身的文件結(jié)構(gòu)極其相似谭溉。這一章主要講解Mod的架構(gòu)和主要文件的作用。其中橡卤,會(huì)重點(diǎn)講解兩個(gè)重要的mod特有文件:modinfo.lua,modmain.lua
架構(gòu)
饑荒的Mod需要遵循一定的文件結(jié)構(gòu)扮念,大體上和游戲根目錄的結(jié)構(gòu)一致,但也有細(xì)微的差別
大致結(jié)構(gòu)圖如下
根目錄下modmain.lua碧库、modinfo.lua,modworldgenmain.lua是三個(gè)Mod特有文件柜与。
scripts文件夾用于放置代碼,內(nèi)部根據(jù)不同的類(lèi)型可以再細(xì)分為prefabs嵌灰,components等弄匕。
exported存放spriter動(dòng)畫(huà)項(xiàng)目,Mod Tools會(huì)自動(dòng)檢查這個(gè)文件夾沽瞭,編譯打包每個(gè)Spriter項(xiàng)目迁匠,以zip文件的形式存放到anim文件夾中。
剩下的文件夾驹溃,anim城丧,images,sound等豌鹤,是用于儲(chǔ)存動(dòng)畫(huà)芙贫、圖片、和聲音資源的傍药。
Mod特有文件
modinfo.lua
記錄Mod的名字磺平,作者,版本號(hào)等基本信息拐辽,也可以編寫(xiě)Mod設(shè)置拣挪,設(shè)置一些常量。這些常量可以在modmain中用特定的Mod API讀取俱诸,從而實(shí)現(xiàn)某些變化菠劝。最重要的一點(diǎn)是,modinfo里可以設(shè)置mod的類(lèi)型睁搭,決定這個(gè)mod是否是客戶(hù)端mod赶诊。如果是主機(jī)端的MOD,是否需要所有的客戶(hù)端都下載园骆。
modinfo的寫(xiě)法是固定的舔痪,不過(guò)有些部分如果不需要,則可以不寫(xiě)锌唾。
編寫(xiě)內(nèi)容如下:
-- 以下3項(xiàng)內(nèi)容會(huì)直接在Mod面板中顯示
name = "從零開(kāi)始做Samansha_03f" -- Mod的名字
author = "LongFei & dangdang & Trica" -- 作者名
description = "教你從零開(kāi)始做Samansha\n\n本教程的美術(shù)資源僅供教學(xué)使用锄码,請(qǐng)勿用于自己發(fā)布的Mod" -- Mod描述
version = "scaffold_03f" -- Mod版本夺英,可以自由設(shè)定任何值,但如果要更新自己的Mod滋捶,就必須和已經(jīng)上傳的Mod版本有差別痛悯。
forumthread = "" -- Mod在klei論壇的地址,沒(méi)有可以留空重窟,但不可刪除
api_version = 10 -- Mod的API版本载萌,當(dāng)前聯(lián)機(jī)版固定為10
dst_compatible = true -- 兼容聯(lián)機(jī)版,因?yàn)槲覀兪亲雎?lián)機(jī)版Mod巡扇,所以此項(xiàng)為true
all_clients_require_mod = true -- 要求所有客戶(hù)端都下載此Mod扭仁。當(dāng)有需要發(fā)送給客戶(hù)端的自定義數(shù)據(jù)時(shí),此項(xiàng)為true霎迫。所謂自定義數(shù)據(jù)有兩類(lèi),一是自定義動(dòng)畫(huà)和圖片帘靡,二是自定義的網(wǎng)絡(luò)變量知给。
icon_atlas = "modicon.xml" -- Mod的圖標(biāo)xml文檔路徑,需要有對(duì)應(yīng)文件存在描姚,否則Mod圖標(biāo)會(huì)顯示為空白涩赢。
icon = "modicon.tex" -- Mod圖標(biāo)文件名稱(chēng)
server_filter_tags = {
"蘇曼莎","中文"
} -- 服務(wù)器過(guò)濾標(biāo)簽,會(huì)在其他人使用標(biāo)簽篩選功能時(shí)起作用轩勘,標(biāo)簽可以寫(xiě)英文也可以寫(xiě)中文筒扒,可以添加多個(gè)標(biāo)簽。
configuration_options = -- 設(shè)置選項(xiàng)绊寻,可以在Mod選擇界面對(duì)Mod的一些參數(shù)進(jìn)行選擇花墩。這些參數(shù)可以在modmain里用GetModConfigData方法讀取
{-- 這個(gè)表中的每一個(gè)元素都是一行選項(xiàng)
{ -- 一個(gè)選項(xiàng)用一張表括起來(lái)
name = "NEW_ACTIONS", -- 選項(xiàng)的標(biāo)識(shí),對(duì)應(yīng)GetModConfigData的第一個(gè)參數(shù)
label = "新動(dòng)作", -- 選項(xiàng)的名稱(chēng)
hover = "添加一組新動(dòng)作澄步,對(duì)全體玩家有效", -- 提示說(shuō)明冰蘑,當(dāng)鼠標(biāo)移動(dòng)到label上時(shí)會(huì)自動(dòng)彈出
options = -- 選項(xiàng)內(nèi)容,每個(gè)元素代表一個(gè)選項(xiàng)值
{
{description = "開(kāi)", data = true}, -- dscripttion是顯示在設(shè)置面板上的值村缸,data是實(shí)際對(duì)應(yīng)的取值
{description = "關(guān)", data = false},
},
default = true, -- 選項(xiàng)的默認(rèn)值祠肥,在選項(xiàng)面板點(diǎn)擊Reset時(shí),會(huì)把該選項(xiàng)的值設(shè)置為默認(rèn)值
},
}
modmain.lua
Mod的入口梯皿,游戲主環(huán)境從這里進(jìn)入Mod執(zhí)行各種內(nèi)容仇箱。modmain的運(yùn)行環(huán)境是獨(dú)立的,如果想要在modmain中編寫(xiě)代碼使用游戲主環(huán)境的全局變量或方法东羹,則需要添加前綴GLOBAL剂桥。比如希望使用STRINGS變量來(lái)添加prefab的名字和描述,就需要添加GLOBAL前綴属提,或者設(shè)置本地變量引用渊额。唯一例外的是Mod API,Mod API是官方提供的一些專(zhuān)門(mén)用于modmain環(huán)境的方法,可以直接在modmain中使用旬迹。其中火惊,有部分游戲主環(huán)境的變量和方法也可以直接在modmain中使用,具體請(qǐng)參考游戲根目錄/scripts/modutil.lua
modmain有多種多樣的寫(xiě)法奔垦,但有些代碼是經(jīng)常會(huì)用到的屹耐,這里簡(jiǎn)單介紹一下。
modmain.lua
PrefabFiles = { -- prefab文件表椿猎,Mod會(huì)自動(dòng)加載scripts/prefabs下的同名lua文件
"lotus_umbrella",
}
-- 一些預(yù)設(shè)置惶岭,防止系統(tǒng)報(bào)錯(cuò),env前綴表示當(dāng)前Mod環(huán)境犯眠,GLOBAL代表游戲主系統(tǒng)的環(huán)境按灶。
-- RECIPETABS,TECH都是游戲主系統(tǒng)中的全局變量筐咧,可以在任意地方使用鸯旁。在加了這些預(yù)設(shè)置,就表明所定義的變量是在env環(huán)境中的了量蕊,下面再使用同名變量就無(wú)需添加GLOBAL前綴了铺罢。
-- 事實(shí)上在Mod環(huán)境中定義的變量,就默認(rèn)是env環(huán)境残炮,完全可以直接使用韭赘,不加env前綴也行。
env.RECIPETABS = GLOBAL.RECIPETABS
env.TECH = GLOBAL.TECH
-- AddRecipe是官方提供的MOD API势就,專(zhuān)門(mén)用在modmian.lua下的泉瞻。參數(shù)非常多,和scripts/recipe.lua里的Recipe類(lèi)的參數(shù)是一一對(duì)應(yīng)的苞冯。
-- 第一個(gè)參數(shù)瓦灶,prefab的名字。
-- 第二個(gè)參數(shù)抱完,配方表贼陶,用{}框起來(lái),里面每一項(xiàng)配方用一個(gè)Ingredient巧娱。Ingredient的第一個(gè)參數(shù)是具體的prefab名碉怔,第二個(gè)是數(shù)量,這里cutgrass和twigs分別是干草和樹(shù)枝禁添。這就表明荷葉傘可以用1干草1樹(shù)枝制作出來(lái)撮胧。
-- 第三個(gè)參數(shù),荷葉傘的歸類(lèi)老翘,RECIPETABS.SURVIVAL表明歸類(lèi)到生存芹啥,也就是可以在生存欄里找到锻离。
-- 第四個(gè)參數(shù),荷葉傘需要的科技等級(jí)墓怀,TECH.NONE 表明不需要科技汽纠,隨時(shí)都可以制造。
-- 后續(xù)5個(gè)參數(shù)都是nil傀履,表明不需要這些參數(shù)虱朵,但需要占位置
-- 最后一個(gè)參數(shù),指明圖片文檔地址钓账,用于制作欄顯示圖片碴犬。
AddRecipe("lotus_umbrella", {Ingredient("cutgrass", 1), Ingredient("twigs", 1)}, RECIPETABS.SURVIVAL, TECH.NONE, nil, nil, nil, nil, nil,"images/inventoryimages/lotus_umbrella.xml")
modimport("prefab_desc") -- 導(dǎo)入其它代碼文件,路徑從Mod根目錄開(kāi)始
從上面的代碼可以看到大致和第一章的modmain的內(nèi)容差不多梆暮,現(xiàn)在只是要新增一個(gè)功能:根據(jù)選項(xiàng)來(lái)設(shè)置荷葉傘的名稱(chēng)服协。代碼可以直接寫(xiě)在modmain里,但這里為了展示modimport
的用法啦粹,我把相關(guān)代碼寫(xiě)成了prefab_desc.lua文件偿荷,然后在modmain.lua中使用modimport
導(dǎo)入。用modimport
導(dǎo)入的文件卖陵,其中的代碼運(yùn)行環(huán)境與modmain相同遭顶。這里就先看看怎樣實(shí)現(xiàn)用選項(xiàng)來(lái)改變荷葉傘名稱(chēng)吧:
prefab_desc.lua
lotus_umbrella_names = {"荷葉傘","春雨","蛙鳴"} -- 定義一張名稱(chēng)表
lotus_umbrella_idx = GetModConfigData("lotus_umbrella_name",true) -- 讀取modinfo中的配置张峰,第一個(gè)參數(shù)是選項(xiàng)標(biāo)識(shí)泪蔫,第二個(gè)是判斷讀取配置還是臨時(shí)配置,一般寫(xiě)true即可喘批。我們?cè)趍odinfo的設(shè)置中儲(chǔ)存的數(shù)據(jù)是整數(shù)1撩荣,2,3饶深,正好就是名稱(chēng)表的整數(shù)索引(lua的表的整數(shù)索引從1開(kāi)始)
env.STRINGS = GLOBAL.STRINGS -- 預(yù)設(shè)置餐曹,不管modmain中有沒(méi)有相同的預(yù)設(shè)置,這里都是一個(gè)獨(dú)立的模塊環(huán)境敌厘。
STRINGS.NAMES.LOTUS_UMBRELLA = lotus_umbrella_names[lotus_umbrella_idx] -- 設(shè)置物體在游戲中顯示的名字
STRINGS.CHARACTERS.GENERIC.DESCRIBE.LOTUS_UMBRELLA = "這傘能擋雨嗎台猴?" -- 物體的檢查描述
STRINGS.RECIPE_DESC.LOTUS_UMBRELLA = "荷葉做的雨傘" -- 物體的制作欄描述
一般來(lái)說(shuō),如果內(nèi)容不多俱两,就可以直接寫(xiě)在modmain里饱狂。但如果有大量的同類(lèi)代碼,比如STRINGS設(shè)置描述宪彩,就可以單獨(dú)寫(xiě)一個(gè)文件休讳,然后用modimport
載入。
modworldgenmain
設(shè)置世界的生成方式尿孔。只有需要更改游戲的地圖生成方式時(shí)俊柔,才需要此文件筹麸。當(dāng)不需要時(shí),可以不添加雏婶。此處略過(guò)物赶,等到講解地圖那一章時(shí)再做詳細(xì)介紹。
靜態(tài)資源
這些文件夾存放各種靜態(tài)資源尚骄,在這里只需要簡(jiǎn)單了解就好块差,后續(xù)用到時(shí)會(huì)做詳細(xì)講解
- anim:存放動(dòng)畫(huà)
- images:存放圖片
- bigportrits:存放人物立繪
- sounds:存放聲音
- exported:存放未編譯的Spriter項(xiàng)目,安裝有Mod Tools時(shí)倔丈,會(huì)自動(dòng)編譯各個(gè)Spriter項(xiàng)目憨闰,打包存放至anim文件夾下。
scripts
scripts文件夾存放了大部分代碼文件需五。其下的文件夾結(jié)構(gòu)和游戲根目錄下的scripts文件夾內(nèi)的結(jié)構(gòu)是一致的鹉动。名字一定要正確拼寫(xiě)而且必須是小寫(xiě),會(huì)在后續(xù)的編程中有用宏邮。
- prefabs:存放自定義的prefab文件
- components:存放自定義的component文件
- widgets:存放自定義的widget文件
- stategraphs:存放自定義SG文件
- brains:存放自定義生物AI文件
另外泽示,如果要在modmain中使用lua內(nèi)置的require函數(shù),那么require的根目錄是scripts文件夾蜜氨。比如require 'config'
械筛,會(huì)在scripts下搜索config.lua
文件并加載。并且飒炎,Mod環(huán)境中沒(méi)有require函數(shù)埋哟,需要先從GLOBAL環(huán)境引用。
作業(yè)
根據(jù)前面所述的內(nèi)容郎汪,從零開(kāi)始搭建一個(gè)Mod赤赊,構(gòu)建和第一章答案一樣的荷葉傘,并實(shí)現(xiàn)荷葉傘的名稱(chēng)可配置煞赢。
在我的網(wǎng)盤(pán)上下載原始素材文件charpter_3_homework.zip
,參考答案charpter_3_answer.zip