第三章 基本框架


这一章的目标是介绍Mod基本结构,让你能够更好地组织代码和各种静态资源。

饥荒Mod采用了隔离良好的设计,每个Mod拥有自己的运行环境,独立于游戏主环境和其它Mod的运行环境。而且单个Mod的文件结构,和游戏本身的文件结构极其相似。这一章主要讲解Mod的架构和主要文件的作用。其中,会重点讲解两个重要的mod特有文件:modinfo.lua,modmain.lua

架构

饥荒的Mod需要遵循一定的文件结构,大体上和游戏根目录的结构一致,但也有细微的差别

大致结构图如下

Mod架构

根目录下modmain.lua、modinfo.lua,modworldgenmain.lua是三个Mod特有文件。
scripts文件夹用于放置代码,内部根据不同的类型可以再细分为prefabs,components等。
exported存放spriter动画项目,Mod Tools会自动检查这个文件夹,编译打包每个Spriter项目,以zip文件的形式存放到anim文件夹中。
剩下的文件夹,anim,images,sound等,是用于储存动画、图片、和声音资源的。

Mod特有文件

modinfo.lua

记录Mod的名字,作者,版本号等基本信息,也可以编写Mod设置,设置一些常量。这些常量可以在modmain中用特定的Mod API读取,从而实现某些变化。最重要的一点是,modinfo里可以设置mod的类型,决定这个mod是否是客户端mod。如果是主机端的MOD,是否需要所有的客户端都下载。

modinfo的写法是固定的,不过有些部分如果不需要,则可以不写。

编写内容如下:

-- 以下3项内容会直接在Mod面板中显示
name = "从零开始做Samansha_03f" -- Mod的名字
author = "LongFei & dangdang & Trica" -- 作者名
description = "教你从零开始做Samansha\n\n本教程的美术资源仅供教学使用,请勿用于自己发布的Mod" -- Mod描述

version = "scaffold_03f" -- Mod版本,可以自由设定任何值,但如果要更新自己的Mod,就必须和已经上传的Mod版本有差别。
forumthread = "" -- Mod在klei论坛的地址,没有可以留空,但不可删除
api_version = 10 -- Mod的API版本,当前联机版固定为10

dst_compatible = true -- 兼容联机版,因为我们是做联机版Mod,所以此项为true
all_clients_require_mod = true -- 要求所有客户端都下载此Mod。当有需要发送给客户端的自定义数据时,此项为true。所谓自定义数据有两类,一是自定义动画和图片,二是自定义的网络变量。


icon_atlas = "modicon.xml" -- Mod的图标xml文档路径,需要有对应文件存在,否则Mod图标会显示为空白。
icon = "modicon.tex" -- Mod图标文件名称


server_filter_tags = { 
    "苏曼莎","中文"
} -- 服务器过滤标签,会在其他人使用标签筛选功能时起作用,标签可以写英文也可以写中文,可以添加多个标签。

configuration_options = -- 设置选项,可以在Mod选择界面对Mod的一些参数进行选择。这些参数可以在modmain里用GetModConfigData方法读取
{-- 这个表中的每一个元素都是一行选项
    { -- 一个选项用一张表括起来
        name = "NEW_ACTIONS", -- 选项的标识,对应GetModConfigData的第一个参数
        label = "新动作", -- 选项的名称
        hover = "添加一组新动作,对全体玩家有效", -- 提示说明,当鼠标移动到label上时会自动弹出
        options = -- 选项内容,每个元素代表一个选项值
        {
            {description = "开", data = true}, -- dscripttion是显示在设置面板上的值,data是实际对应的取值
            {description = "关", data = false},
        },
        default = true, -- 选项的默认值,在选项面板点击Reset时,会把该选项的值设置为默认值
    },
}
Mod选择面板
Mod设置面板(待更换).png

modmain.lua

Mod的入口,游戏主环境从这里进入Mod执行各种内容。modmain的运行环境是独立的,如果想要在modmain中编写代码使用游戏主环境的全局变量或方法,则需要添加前缀GLOBAL。比如希望使用STRINGS变量来添加prefab的名字和描述,就需要添加GLOBAL前缀,或者设置本地变量引用。唯一例外的是Mod API,Mod API是官方提供的一些专门用于modmain环境的方法,可以直接在modmain中使用。其中,有部分游戏主环境的变量和方法也可以直接在modmain中使用,具体请参考游戏根目录/scripts/modutil.lua

modmain有多种多样的写法,但有些代码是经常会用到的,这里简单介绍一下。

modmain.lua

PrefabFiles = { -- prefab文件表,Mod会自动加载scripts/prefabs下的同名lua文件
    "lotus_umbrella",
}


-- 一些预设置,防止系统报错,env前缀表示当前Mod环境,GLOBAL代表游戏主系统的环境。
-- RECIPETABS,TECH都是游戏主系统中的全局变量,可以在任意地方使用。在加了这些预设置,就表明所定义的变量是在env环境中的了,下面再使用同名变量就无需添加GLOBAL前缀了。
-- 事实上在Mod环境中定义的变量,就默认是env环境,完全可以直接使用,不加env前缀也行。
env.RECIPETABS = GLOBAL.RECIPETABS 
env.TECH = GLOBAL.TECH


-- AddRecipe是官方提供的MOD API,专门用在modmian.lua下的。参数非常多,和scripts/recipe.lua里的Recipe类的参数是一一对应的。
-- 第一个参数,prefab的名字。
-- 第二个参数,配方表,用{}框起来,里面每一项配方用一个Ingredient。Ingredient的第一个参数是具体的prefab名,第二个是数量,这里cutgrass和twigs分别是干草和树枝。这就表明荷叶伞可以用1干草1树枝制作出来。
-- 第三个参数,荷叶伞的归类,RECIPETABS.SURVIVAL表明归类到生存,也就是可以在生存栏里找到。
-- 第四个参数,荷叶伞需要的科技等级,TECH.NONE 表明不需要科技,随时都可以制造。
-- 后续5个参数都是nil,表明不需要这些参数,但需要占位置
-- 最后一个参数,指明图片文档地址,用于制作栏显示图片。
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") -- 导入其它代码文件,路径从Mod根目录开始

从上面的代码可以看到大致和第一章的modmain的内容差不多,现在只是要新增一个功能:根据选项来设置荷叶伞的名称。代码可以直接写在modmain里,但这里为了展示modimport的用法,我把相关代码写成了prefab_desc.lua文件,然后在modmain.lua中使用modimport导入。用modimport导入的文件,其中的代码运行环境与modmain相同。这里就先看看怎样实现用选项来改变荷叶伞名称吧:

prefab_desc.lua

lotus_umbrella_names = {"荷叶伞","春雨","蛙鸣"} -- 定义一张名称表
lotus_umbrella_idx = GetModConfigData("lotus_umbrella_name",true) -- 读取modinfo中的配置,第一个参数是选项标识,第二个是判断读取配置还是临时配置,一般写true即可。我们在modinfo的设置中储存的数据是整数1,2,3,正好就是名称表的整数索引(lua的表的整数索引从1开始)

env.STRINGS = GLOBAL.STRINGS -- 预设置,不管modmain中有没有相同的预设置,这里都是一个独立的模块环境。
STRINGS.NAMES.LOTUS_UMBRELLA = lotus_umbrella_names[lotus_umbrella_idx] -- 设置物体在游戏中显示的名字
STRINGS.CHARACTERS.GENERIC.DESCRIBE.LOTUS_UMBRELLA = "这伞能挡雨吗?" -- 物体的检查描述
STRINGS.RECIPE_DESC.LOTUS_UMBRELLA = "荷叶做的雨伞" -- 物体的制作栏描述

一般来说,如果内容不多,就可以直接写在modmain里。但如果有大量的同类代码,比如STRINGS设置描述,就可以单独写一个文件,然后用modimport载入。

modworldgenmain

设置世界的生成方式。只有需要更改游戏的地图生成方式时,才需要此文件。当不需要时,可以不添加。此处略过,等到讲解地图那一章时再做详细介绍。

静态资源

这些文件夹存放各种静态资源,在这里只需要简单了解就好,后续用到时会做详细讲解

  • anim:存放动画
  • images:存放图片
  • bigportrits:存放人物立绘
  • sounds:存放声音
  • exported:存放未编译的Spriter项目,安装有Mod Tools时,会自动编译各个Spriter项目,打包存放至anim文件夹下。

scripts

scripts文件夹存放了大部分代码文件。其下的文件夹结构和游戏根目录下的scripts文件夹内的结构是一致的。名字一定要正确拼写而且必须是小写,会在后续的编程中有用。

  • prefabs:存放自定义的prefab文件
  • components:存放自定义的component文件
  • widgets:存放自定义的widget文件
  • stategraphs:存放自定义SG文件
  • brains:存放自定义生物AI文件

另外,如果要在modmain中使用lua内置的require函数,那么require的根目录是scripts文件夹。比如require 'config',会在scripts下搜索config.lua文件并加载。并且,Mod环境中没有require函数,需要先从GLOBAL环境引用。

作业

根据前面所述的内容,从零开始搭建一个Mod,构建和第一章答案一样的荷叶伞,并实现荷叶伞的名称可配置。
在我的网盘上下载原始素材文件charpter_3_homework.zip,参考答案charpter_3_answer.zip

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容