第三章 基本框架


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

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

架构

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

大致结构图如下

第三章 基本框架_第1张图片
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时,会把该选项的值设置为默认值
    },
}
第三章 基本框架_第2张图片
Mod选择面板
第三章 基本框架_第3张图片
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

你可能感兴趣的:(第三章 基本框架)