泰拉瑞亚Mod开发指南
Hello World
- 欢迎来到泰拉瑞亚的创意无限世界,在这里,不仅仅是探索与冒险,更是创造与实现梦想的天地。作为一名勇敢的开发者,你即将他上的旅程,不近视深入这个像素世界的腹地,更是要在其基础上构建属于你自己的奇迹。本指南将是你受众的罗盘,引领你步入泰拉瑞亚模组开发的神秘大门。
- 想象一下,当你手持代码之间,桥下第一个字符,一个简单的"Hello World"便能在泰拉瑞亚广阔的天地间回响,这不仅是变成传统的直径,也是你成为游戏世界造物主的第一步。泰拉瑞亚mod开发的魅力,在于它赋予你重塑世界规则的能力,无论是新奇的武器、独特的怪物,还是整个异世界的创造,一切皆有可能。
- 本指南将循序渐进,从最基础的设置环境开始,逐步深入如何使用C#和TModLoader来编写你的第一个mod,理解背后的逻辑与技巧,为你后续的创意开发打下坚实的基础。
- 无论你是编程新手,还是经验丰富的开发者初涉游戏领域,这篇指南都力求让你的每一步学习都充满乐趣与成就感。准备好了吗?让我们异同步入泰拉瑞亚的编程仙境,用一行行代码编制出属于你的传奇故事。
- 让我们开始吧!
Mod制作准备
- 一台电脑
- 玩过泰拉瑞亚,原版或者灾厄至少通关过一次(博主原版大师、灾厄死亡大师都通关了)
- 安装IDE,强烈建议VSCode,主要是写C#
- 会使用画图软件(Photoshop等)
.NET环境安装
- 开发环境的安装,可以直接看微软官方教程
- 这里再建议安装一个通义灵码的插件,用起来还是挺方便的
TModLoader的介绍与安装
源码Mod和TML Mod的区别
- 源码Mod的制作方法是通过反编译泰拉瑞亚源码,并在此基础上修改而制作的模组。优点是自由度高,可以实现的功能多。缺点是很难管理,灵活度低下,尤其是当Mod规模扩大的时候。
- TML Mod通过提供原版的接口使得开发者可以在一个与原版独立的环境开发Mod,也就是说,开发者可以不用关注原版冗长的代码实现细节,而是与接口进行互动。优点是管理方便、灵活。缺点是实现的功能具有局限性,有时候需要等待TML开发者添加了某些接口才能实现特定的功能。但是随着TML这么多年功能的不断的完善,以及原版泰拉瑞亚代码越来越晦涩难懂,TML开发最终占据了主导。
TModLoader的安装
-
如果你之前打过mod玩,那么其实你已经安装好了,对吧
-
如果你是第一次使用mod游玩,直接在Steam上下载安装即可
-
安装完成之后,直接TMOD,启动!
-
点击创意工坊,进入创意工坊中心
-
点击开发模组,会看到如下页面
第一个Mod
-
点击右下角创建模组,填写模组信息我们就可以初始化一个模组项目了
- ModName:模组名称,不要夹杂空格
- Mod DisplayName:模组显示名称
- Mod Author:模组作者
- BasicSword:初始之剑,这里填写的是剑的名称,创建项目时,会自动生成这把剑的初始化代码
-
点击创建后,初始化的项目如下
-
我们在VSCode里打开这个项目,首先看一下目录结构
[ModName].cs
:这是Mod类。它是任何Mod的核心文件,每个Mod只能存在一个Mod类,对于简单的Mod,这个文件会非常简洁,但是这个类中可以发生各种全局性的事情。description.txt
:包含Mod的描述文本,在Mod菜单中点击“更多信息”按钮可以在游戏中查看。如果你愿意,可以创建一个带有额外BBCode格式的description_workshop.txt文件,该文件将在Steam创意工坊网站上显示。build.txt
:包含Mod的版本、作者和显示信息。可以包含其他值。这个文件是必要的。icon.png
:在游戏中显示的80x80图标。你可以为Steam创意工坊创建一个更详细或更高分辨率的icon_workshop.png图标,该文件可以达到512x512像素。[ModName].csproj
:为Visual Studio设置的项目文件,用于调试你的Mod。调试非常有用,但需要一些学习,不要删除它。Properties/launchSettings.json
:与ModName.csproj相关,包含用于调试tModLoader文件路径,不要删除,随着你的经验积累,它会变得很有用。Content/Items/[ItemName].cs
:一个简单的剑物品。以此作为示例,学习如何制作其他ModItem类。Content/Items/[ItemName].png
:对应的物品图像。Localization/en-US_Mods.[ModName].hjson
:包含Mod中内容的英文文本。它目前包含生成的剑的显示名称和工具提示。这个文件会随着你向Mod添加新内容而自动更新条目。请参阅Localization Wiki了解更多本地化及支持其他语言的信息。
-
下面我们直接来看初始化剑的代码,以及对应的配置文件信息。
- 下面这段代码就是初始之剑的代码,我们先来看
SetDefaults()
方法,这个方法就是初始化物品的配置信息,这里我们配置了物品的伤害、攻击类型、宽高、使用时间、使用动画、使用方式、击退、价值、稀有度、音效、自动使用(近战武器自动挥舞)等。 - 同时我们需要关注
AddRecipes()
方法,这个方法就是添加物品的合成配方,这里我们添加了合成配方,需要用10个土块,并且需要工作台才可以制作。
1 | using Terraria; |
- 那我们现在加载Mod,并且进入游戏
- 建造一个工作台,并且使用10个土块,即可制造我们的初始之剑
- 50点伤害有点不够看啊,那我们现在修改一下武器伤害以及攻击间隔,随后重新构建并加载我们的Mod,然后再次进入游戏
1 | using Terraria; |
- 在这里可以配置Mod物品的显示名称和提示信息。
1 | # This file will automatically update with entries for new content after a build and reload. |
- 修改初始之剑的名称以及描述
1 | Items: { |
Basic Item
- 本小节旨在解释所有Item之间的共同点。
什么是物品(What is an Item)?
- 了解物品(Item)、抛射物(Projectiles)和方块(Tiles)之间的区别非常重要。刚开始时,如果你不清楚它们的不同之处,可能会无意中混淆概念。例如,有些人可能会混淆并试图将
工作台物品(Item)
添加到配方
中,而实际上他们想要添加的是工作台方块(Tile)
。还需要意识到,像回旋镖武器这样的东西实际上由物品和抛射物组成。虽然这是一个简单的概念,但请记住这一点。
制作物品(Making an Item)
- 要将物品添加到泰拉瑞亚,我们首先必须创建一个类,该类需要继承
ModItem
,实际上上面小节中的[ModName].cs
就是个样例,在创建Mod的时候已经为我们生成了一把剑的物品。
设置默认值
- 物品最重要的部分是
SetDefaults
。SetDefaults
是设置物品属性的地方,例如物品使用什么弹药、物品的大小以及物品放置的是哪个方块。请参阅 Item 类文档 ,了解在 SetDefaults 中常见的设置值的含义。你还可以通过访问 Vanilla Item 来查看原版物品字段值。
本地化
- 构建你的 Mod 后,本地化文件通常位于 My Games\Terraria\tModLoader\ModSources\MyModName\Localization\en-US_Mods.MyModName.hjson,将会填充有新添加物品的条目。对于物品,你会看到 DisplayName 和 Tooltip 的条目。DisplayName 将默认为类名,单词之间用大写字母分隔。Tooltip 默认为空。你可以编辑此文件以自定义这些本地化内容:
1 | Items: { |
Basic Projectile
- 在学习向量以及计算几何的知识之前,最好能先创建一个自己的弹幕。这样我们可以通过这个弹幕观察到数学是如何发挥作用的。
弹幕基础
什么是Projectile
- 在开始修改弹幕之前,我们需要先了解物品和弹幕之间的区别。物品是可以存储在库存中(例如背包、箱子等)的对象,而弹幕时从武器或者敌人射出的对象,例如子弹、箭等。
什么情况下会使用弹幕?
- 在泰拉瑞亚中,许多物品因为弹幕的存在而具有功能性,例如枪和弓(子弹和箭)、激光、炸弹和其他投掷物品,以及大多数魔法武器,甚至一些抓钩、连枷、长矛、宠物、召唤物、钻头和悠悠球,也会生成弹幕。很多敌怪也可以生成弹幕。
创建基本弹幕
- 在创建弹幕之前,我们最好先规范一下目录结构,为后续所有的弹幕建立一个单独的文件夹,名为Porjectiles;同时也为刚刚的剑创建一个单独的文件夹,名为Sowrds。
- 随后在Projectiles目录下创建
[ProjectileName].cs
和[ProjectileName].png
(弹幕贴图)文件。创建弹幕时,我们需要继承ModProjectile
类,同时需要实现SetDefaults
方法,SetDefaults
方法中需要设置弹幕的属性,例如弹幕的大小、弹幕的速度、弹幕的伤害、弹幕的伤害类型等。 - 下面代码中的
namespace
需要替换为你自己的模组文件夹名/命名空间。
1 | using Terraria; |
应用弹幕
- 在刚刚我们已将创建好了一个弹幕,现在我们将其作用于武器上
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33+ using MyFirstMod.Content.Items.Projectiles;
using Terraria;
using Terraria.ID;
using Terraria.ModLoader;
namespace MyFirstMod.Content.Items.Swords
{
public class Excalibur : ModItem
{
public override void SetDefaults() {
Item.damage = 99999999;
Item.DamageType = DamageClass.Melee;
Item.width = 40;
Item.height = 40;
Item.useTime = 5;
Item.useAnimation = 5;
Item.useStyle = ItemUseStyleID.Swing;
Item.knockBack = 6;
Item.value = Item.buyPrice(silver: 1);
Item.rare = ItemRarityID.Blue;
Item.UseSound = SoundID.Item1;
Item.autoReuse = true;
+ Item.shoot = ModContent.ProjectileType<MyFirstProjectile>();
}
public override void AddRecipes() {
Recipe recipe = CreateRecipe();
recipe.AddIngredient(ItemID.DirtBlock, 10);
recipe.AddTile(TileID.WorkBenches);
recipe.Register();
}
}
} - 重新编译并加载Mod,进入游戏,挥舞武器,可以看到我们刚刚制作的弹幕已经生成了。
SetDefaults
- 弹幕最重要的部分是SetDefaults方法。该方法是设置弹幕值的地方,例如命中宽度和高度、弹幕是友军还是敌军、以及弹幕将使用哪个AI。请参阅弹幕类文档以了解通常设置的值的含义。还可以通过放温暖Vanilla弹幕字段值来查看Vanilla弹幕值。
Projectile.Damage
- 一个常见的错误是在SetDefaults中设置Projectiles.Damage,这不起作用,因为弹幕的伤害值总是被生成弹幕时传递给Projectile.NewProjectile的值覆盖。通常,生成弹幕的物品或NPC将决定伤害值。
Other Hooks/Methods
- ModProjectile文档列出了许多其他钩子/方法,您可以使用它们生成独特的弹幕。例如在弹幕击中敌人时施加减益效果,可以使用OnHitNpc方法,要在弹幕击中物块时做些事情,可以使用OnTileCollide方法。
What is AI
- 弹幕的AI是弹幕最重要的方面,它控制弹幕在生成后如何移动和行动,对于新手模组开发者来说,最简单的方法是通过设置
Projectile.aiStyle = #
和AIType = ProjectileID.NameHere
来一来其他原版弹幕已经使用的AI代码。你分配给Projectile.aiStyle
的值应该与ProjectileID.NameHere
的值相匹配。这杯成为模仿原版弹幕。 - 随着你对更高级的弹幕移动行为的需求,你会发现模仿原版弹幕AI非常有限,所以下面我们将讨论如何自定义AI。
使用原版AI
- 我们可以使用原版AI来初始化我们的弹幕。让我们制作一个回旋镖,使用和原版回旋镖弹幕相同的aiStyle。我们可以在中查找回旋镖弹幕,可以看到原版回旋镖使用的aiStyle为3。
- 那么我们可以在代码中使用
Projectile.aiStyle = 3;
,或者将3改为ProjectileID.Boomerang
,增强代码的可读性。 - 为了让这个回旋镖更简单,我们可以使用
Projectile.CloneDefaults(ProjectileID.EnchantedBoomerang);
,这将复制所有其他的默认值。这样,你将获得一个与原版回旋镖行为相同的弹幕。 - 通过设置AIType可以改变弹幕的粒子特效。
- 请注意,武器贴图请自行解决。
1 | using MyFirstMod.Content.Items.Projectiles; |
1 | using Terraria; |
1 | using Terraria; |
- 重新编译并加载Mod,进入游戏,我们就可以使用10个土块在工作台旁制作我们刚刚编写的回旋镖了。亲测手感和原版几乎无异(虽然我也不怎么用回旋镖武器就是了)。
自定义AI
- 本小节将讨论你可以在AI中添加的元素,记得如果使用
Projectile.CloneDefaults
复制其他弹幕默认值,要将Projectile.aiStyle
的值设回0
。所有自定义AI的代码都放在ModProjectile.AI
方法中。也就是重写AI()方法
1 | using Terraria; |
Timers
- Timers:计时器
- 许多弹幕使用计时器来延迟动作。通常我们使用
Projectile.ai[0]
或Projectile.ai[1]
,因为这些值会自动同步,这里我们计数到30,换句话说,半秒。
1 | Projectile.ai[0] += 1f; |
Gravity
- Gravity:重力
- 弹幕实际上没有重力,每个带有重力移动的弹幕实际上是它们的AI代码实现了重力。要实现重力,只需要在
Projectile.velovity.Y
中添加一个小值。
1 | Projectile.velocity.Y = Projectile.velocity.Y + 0.1f; // 0.1f 是箭的重力,0.4f 是飞刀的重力 |
- 根据上述的计时器和重力的设定,我们现在可以写一个延迟重力效果
1 | Projectile.ai[0] += 1f; // 使用计时器等待15个刻度后再应用重力。 |
Wind Resistance
- Wind Resistance:风阻
- 纵向的加速度是重力控制的,那么横向的加速度是风阻控制的。
- 通过减少
Projectile.velocity.X
的乘积系数,我们可以轻松实现风阻。结合计时器,我们同样可以让弹幕越来越慢,实现类似蜜蜂手雷的效果。(打肉山的时候,在平台扔蜜蜂手雷,一开始速度蛮快的,但是会越来越慢,直至爆炸)
1 | Projectile.ai[0] += 1f; |
Rotation
- Rotation:旋转
恒定旋转
- 我们可以在AI中添加
Projectile.rotation
使其想回旋镖一样旋转。
1 | Projectile.rotation += 0.4f * Projectile.direction; |
面向前方
自定义坐骑
评论