为Alien Swarm: Reactive Drop 开发MOD
文章目录
我以后玩游戏的时间越来越少了..分享下这个游戏mod制作方法., 没有编程基础也能做, 如果有编程基础的话,可以做出很多高级的mod来.
工具
1,Alien Swarm: Reactive Drop-sdk [steam - 库 - 工具 ] (官方开发套件 约90M ,先装游戏,再装SDK,已经安装了游戏,直接安装SDK)
2,GCFScape [下载] (mod解包工具 , 约500KB )
下文简称 SDK 和 解包工具.
3,任意记事本编辑工具,推荐用notepad++ ,否者可能中文显示有问题.
官方开发文档网页版
1, 控制台参数/控制台命令 --> 链接
2, mod函数 --> 链接
路径
我的游戏路径是:
D:\Program Files (x86)\Steam\steamapps\common\Alien Swarm Reactive Drop\
但是对于mod文件,真正的根目录应该是
D:\Program Files (x86)\Steam\steamapps\common\Alien Swarm Reactive Drop\reactivedrop\ <--下文简称根目录.
已安装的mod文件所在目录
创意工坊mod文件下载所在目录
D:\Program Files (x86)\Steam\steamapps\workshop\content\563560\
自己测试,本地安装mod目录
D:\Program Files (x86)\Steam\steamapps\common\Alien Swarm Reactive Drop\reactivedrop\addons\
下文我都将本地测试mod目录 简称为 MOD目录 .
从山寨开始了解MOD
我用4fun (创意工坊链接) 为例子.订阅后.steam自动下载后.
可以在创意工坊mod目录可以找到1112385907/addon.vpk
用解包工具打开.
解包
解包方式有两种,
1,鼠标按住root 拖动到一个本地文件夹
2,在root 上右键 Extract 导出到一个指定目录
解包后你会发现它的目录和游戏目录是一一对应的. (ROOT目录对应游戏根目录)
而里面多数都是文本文件,甚至记事本都能编辑.
现在做个简单实验
1,取消订阅4fun mod (游戏关闭状态) ,并在创意工坊下载mod目录里面确认这个mod被删除了.没被删就手动删.
2,运行游戏,单人开房,确认挑战里面已经没有 4fun 模式了.
2,游戏无需关闭, 直接将解包的mod文件复制游戏根目录,注意一一对应
3,退到游戏主菜单,你也可以重启游戏, 单人开房,看看挑战里面是不是又有4fun了.
创意工坊mod vpk文件工作模式,感觉就像解压后放游戏目录. (实际它的工作方式更像linux系统的挂载/软链接方式;window系统的快捷方式)
到这里,你只要了解,在游戏根目录放入特殊的文件,mod就能跑起来.
挑战: resource\challenges
挑战导演系统: resource
脚本:scripts , scripts\vscripts
地图:maps , maps\graphs , materials\vgui\swarm\
地图选择: resource , resource\campaigns, resource\overviews
模型:models , materials\models
多拆两个包.多看看别人怎么做的.
制作一个山寨挑战mod
现在拿我山寨的4fun挑战mod拿出来讲解.
创建一个挑战文件
新建一个文本文件,名字随意,建议小写英文或者追加数字的组合.
游戏根目录\resource\challenges\tl2.txt (注意这里用的是tl2 ,尽量不要和官方文件重名,原因后面我说补充说下. )
文件内容如下
"CHALLENGE" {
"name" "屠杀场/跳跃版"
"description" "山寨版本的4FUN,基于4FUN改进中,尽可能地支持MOD地图"
"convars" {
rd_ready_mark_override 1 //自动准备
rd_weapons_regular_allowed "7 27" //7弹药箱 27灭火器
rd_weapons_regular_allowed_inverted 1
rd_weapons_extra_allowed "1 2 5 12 19 18 20 8 15"
rd_weapons_extra_allowed_inverted 1
rd_weapon_requirement_override 1
rd_weapons_regular_class_unrestricted "1 2 3 15"
rd_weapons_extra_class_unrestricted 11
rd_techreq 0
rd_hackall 1
rd_weapons_show_hidden 1 //显示隐藏武器.
rd_player_bots_allowed 0 //禁止选机器人
asw_wanderer_override 1 //锁定猛攻
asw_marine_ff_absorption 0 //锁定友伤方式
}
}
name 就是挑战名,支持中文.
description 挑战描述,支持中文
convars 就是参数设置. 自己参考前面我提供的官方文档链接.
ps:
这里参数主要作用于大厅.主要作用 用来限制/或解锁武器, 游戏地图限制必须要技术的, 这里也可以取消限制.
这些参数实际会作用到游戏里.这里可以把所有变量写这里,不过不建议.
测试:
你重新开单人房间,你就发现里面有这个 屠杀场/跳跃版 挑战了.
这是最基本的挑战mod文件.光这个文件就能跑起来.
创建挑战MOD脚本
光参数并不能完美实现你要的功能,那么就需要用到脚本文件了.
脚本文件是自动载入制度.
前面我的挑战名字 tl2.txt
那么
我们新建一个后缀为nut的文件. 名为 challenge_挑战文件名.nut
游戏根目录\scripts\vscripts\challenge_tl2.nut
这个脚本文件会在游戏开始后自动加载.你可以把你所有需要的功能写这个文件里..
我更喜欢challenge_tl2.nut用IncludeScript包含脚本文件的方式引入其他脚本.
//为行注释符.
//基本参数
IncludeScript("tl_cvar.nut");
//难度控制
IncludeScript("tl_skill_level.nut");
//函数
IncludeScript("tl_fun.nut");
//恢复弹药逻辑脚本
IncludeScript("tl_regen_ammo.nut");
//武器伤害/反伤逻辑脚本
IncludeScript("tl_damage.nut");
//钩子
IncludeScript("tl_even.nut");
//地图fix
IncludeScript("tl_map_fix.nut");
另外在 游戏根目录\scripts\vscripts\ 新建一个tl_cvar.nut 放我的参数变量. (和challenge_tl2.nut 同目录)
另外在 游戏根目录\scripts\vscripts\ 新建一个tl_skill_level.nut 放我的难度控制脚本.
另外在 游戏根目录\scripts\vscripts\ 新建一个tl_fun.nut 放我的函数脚本.
...类推
我感觉这样逻辑比较清晰.
设置参数方式得用命令
Convars.SetValue( "rd_sentry_invincible", 1 ); //炮台无敌
放上我tl_cvar.nut文件部分代码.
//~~~~~~~~~子弹设置部分~~~~~~~~
//炮台无限子弹
Convars.SetValue( "asw_sentry_infinite_ammo", 1 );
//医疗步枪 无限医疗
Convars.SetValue( "rd_medgun_infinite_ammo", 1 );
//不删除空装备
Convars.SetValue( "rm_destroy_empty_weapon", 0 );
//隐藏备用弹夹数量(无限子弹模式好看点)
Convars.SetValue( "rd_hud_hide_clips", 1 );
//没有弹药的时候不提示
Convars.SetValue( "rd_notify_about_out_of_ammo", 0 );
//~~~~~~~~~技能部分~~~~~~~~
//技术工程能力--快速放炮台
Convars.SetValue( "asw_skill_engineering_sentry_base", 99 );
//~~~~~~~~~武器部分~~~~~~~~
//缩小沙漠之鹰对特殊怪的伤害
Convars.SetValue( "rd_deagle_bigalien_dmg_scale", 1 );
//电甲持续时间
Convars.SetValue( "asw_electrified_armor_duration", 30 );
//灭火器冰冻量(默认为0不可冰冻怪物)
Convars.SetValue( "rd_extinguisher_freeze_amount", 0.2 );
//灭火器伤害 4fun为0.1
Convars.SetValue( "rd_extinguisher_dmg_amount", 0.2 );
//手雷导火索长度 (疑似引燃时间)
Convars.SetValue( "asw_cluster_grenade_child_fuse_max", 2 );
//手雷分裂数量
Convars.SetValue( "asw_skill_grenades_clusters_base", 5 );
这样,参数分类,加上注释, 以后要修改也比较方便.
官方文档也不太完美,我英文能力又差,很多变量理解上有点问题..官方文档解释不清楚的,一半靠蒙,一半靠游戏测试参数去理解.
脚本基本用法
变量定义
属于弱类型语法,可以不定义直接使用
定义有两种方式,一种是反向箭头
ent <- null; //对象,枚举类型 推荐用这种方法
另外可以用等号表示
hNearEnt = null;
默认为全局变量.
想要定义局部变量 加 local 前缀
local hNearEnt = null;
类型转换也有自动转换.
逻辑语法
看官方文档只看到这四种语法 ,用法和C/C++一样. 跳出循环,跳过循环的用法一样.
if ,for , while,switch/case
完整参考语法文档
http://squirrel-lang.org/doc/squirrel3.html
钩子函数
游戏脚本自带几个钩子函数,在满足特定条件下触发
OnTakeDamage_Alive_Any
触发伤害函数,无论是怪打你,还是你打怪,还是你自己炸到你自己.都会被触发
UserConsoleCommand
用户使用控制台命令触发此函数.
OnGameEvent_x
响应游戏某个事件,这里x是代替值,实际应用有很多,玩家加入,玩家离开,角色死亡,捡取弹药...
举例
OnGameEvent_sentry_complete //炮台搭建完成
OnGameEvent_weapon_reload_finish //弹药装填完毕
具体完整列表在这两个文件,事件名和参数都有说明.
文件1 -> 链接
文件2 -> 链接
OnMissionStart
当任务开始,或者理解为游戏开始触发.
Update
定时执行钩子函数,这个函数最终返回一个浮点型,这个数值就是下次执行该函数的间隔.
脚本实例讲解
4fun mod中有个,所有人死亡自动重启任务效果,这个就是钩子用法.
我将他代码做了一些改进.
//钩子 死亡(异形和玩家死亡都会触发)
function OnGameEvent_entity_killed(params)
{
//读取死亡者
local victim = EntIndexToHScript(params["entindex_killed"]);
//如果死掉的是海军陆战队成员
if (victim != null && victim.GetClassname() == "asw_marine"){
if (marinesTable.rawin(victim)){
//当海军陆战队死亡后在存活表中移除
marinesTable.rawdelete(victim);
//当全部死亡,重启任务
if (marinesTable.len() == 0){
//4fun 这里是直接重启任务,这里如果直接重启的话,所有玩家都无法获得经验.
//正常游戏失败了是有经验的,虽然比较少.
//创建一次性定时器
//通过延时1秒所有人都能获得经验.
//创建计时器
local timer = Entities.CreateByClassname("logic_timer");
//应该是循环间隔
timer.__KeyValueFromFloat("RefireTime", 1);
//先停止定时器(因为定时器脚本还没挂载)
DoEntFire("!self", "Disable", "", 0, null, timer);
//验证脚本作用域??
timer.ValidateScriptScope();
//用另外一个函数来接管,类似回调函数
local timerScope = timer.GetScriptScope();
//回调函数
timerScope.Delay <- function()
{
//重启任务
Director.RestartMission();
self.DisconnectOutput("OnTimer", "Delay");
//计时器销毁
self.Destroy();
}
//链接计时器作用域脚本
timer.ConnectOutput("OnTimer", "Delay");
//激活计时器
DoEntFire("!self", "Enable", "", 0, null, timer);
}
}
}else {
//死的不是玩家的时候,这里4fun有
//当火蚊子死亡的时候,停止蚊子声音(预保留)
if (victim.GetName() == "asw_tl_buzzer"){
victim.StopSound("d1_town.LargeFireLoop");
victim.StopSound("d1_town.LargeFireLoop");
}
}
}
导演文件
导演文件乃是文档最少的,官方wiki甚至没提这个玩意.
导演文件是控制生成的特殊脚本. 仅仅在猛攻模式生效。4FUN脚本中 带了猛攻,所以开不开猛攻4fun怪一样多。
相对于挑战文件
游戏根目录\scripts\vscripts\challenge_tl2.nut
那么自动执行的导演文件有两种.
alien_selection_tl2.txt
alien_selection_对应地图名_tl2.txt
标有地图名字的脚本应该优先级会更高.
这个文件自己研究.
打包
1,游戏外面,比如你桌面或者C盘新建一个root文件夹.
2,然后根据前面 挑战文件,导演文件,脚本 对应的文件放root目录,注意它们和游戏根目录对应规则.
用命令
D:\Program Files (x86)\Steam\steamapps\common\Alien Swarm Reactive Drop\bin\vpk.exe "C:\root\"
会在root目录生成一个vpk文件.
发布
在游戏中,创意工坊新建一个mod,打个名字,和描述(目前只能打英文或者数字 后面上传后可以改中文),
然后设置一个封面图片.
然后选择你的VPK文件,点发布即可.上传完毕后,会自动打开浏览器,就是你这个mod创意工坊链接.
这时这个mod只能你自己访问. 你把mod设置公共访问就可以其他人订阅了.
更新
有更新的话,只要在游戏中重新上传新的VPK包即可.
注意事项
1,不要和官方文件重名. 覆盖官方文件会导致你进不去公共服务器. (比如你修改武器模型)
游戏会检验本地和服务器核心文件是否相同.
2,不要和其他mod文件名字相同.
如果你也叫个挑战也用4fun.txt ,如果你服务器同时开启4fun和你这个同名4fun,那么在挑战列表里面只会出现一个挑战.
回到前文看下MOD工作方式你就知道为啥了.
ps : 你可以叫个8fun.txt (只要文件不冲突) ,文件内描述可以和4fun一样. 这样服务器同时启用两个mod,就能在挑战列表看到两个4fun.
3,版权问题
山寨的mod不要上传到创意工坊,除非取得作者同意.
或者代码用抄袭别人的.都不要上传创意工坊.
国外版权意识很强.