杀戮尖塔Mod制作入门:环境配置与Maven工程构建指南

发布时间:2026/10/23 16:11:17
杀戮尖塔Mod制作入门:环境配置与Maven工程构建指南

简介:《杀戮尖塔Mod制作入门1》是一份面向游戏玩家与Java初学者的模组开发教程。资源以《杀戮尖塔》为例,系统讲解从环境搭建到实际编码的完整流程,包括订阅ModTheSpire、STSLib、BaseMod三大支持库,安装IntelliJ IDEA与Maven,以及通过pom.xml配置游戏路径和依赖等关键步骤。正文还对控制台输出、变量与函数、类作用域、监听函数与继承等基础概念作了入门介绍,适合希望为游戏添加自定义卡牌、角色或机制的开发者参考。资源包含1个PDF文档,整体大小约1.5MB,内容组织紧凑。目前已有2121人学习下载,教程中的模块划分和代码示例对零基础者较为友好,照着搭建环境可避开常见踩坑点。通过学习,读者能独立创建第一个Maven工程并理解杀戮尖塔Mod的基本结构,为后续更复杂的Mod开发打下基础。

1. 杀戮尖塔Mod制作入门:先把环境装成能跑的样子

很多卡在杀戮尖塔Mod制作第一步的人,并不是代码写不出来,而是环境根本没对齐。我也见过不少照着教程走到一半就翻车的:游戏本体装好了,创意工坊里也订阅了支持库,结果打开IntelliJ IDEA建Maven工程时,pom.xml里三个依赖路径全是错的,一编译就是满屏红色报错;或者好不容易package成功,进游戏在ModTheSpire界面里却看不到自己那个mod的名字。问题几乎都出在「三件套装没装齐、路径指没指对、版本对不对得上」这三件事上。

杀戮尖塔本体是Java写的,mod本质上是把你自己写的Java代码打包成jar,再通过ModTheSpire这个加载器塞进游戏进程里。整套开发环境的核心就三样:游戏本体加支持库(Basemod、ModTheSpire、stslib)、一个Java IDE、一个能构建jar的Maven。这篇笔记就把这三样从下载到配置再到跑通第一个mod的完整流程写清楚,适合第一次接触Java和Maven的mod新手,也适合之前配过环境但一直没跑通的开发者对照排查。

2. 环境准备:游戏本体、支持库与Maven的版本选择

2.1 先订阅三个支持库:Basemod、ModTheSpire、stslib

先明确一个概念:杀戮尖塔的mod几乎都依赖三大支持库——modthespire、stslib和basemod。Basemod提供基础的mod注册和订阅框架,ModTheSpire是mod加载器(游戏启动时会先拉起它的界面让你勾选要加载的mod),stslib则提供更多扩展API,比如自定义卡牌颜色、特殊能量机制等。三者缺一不可,尤其是前两个,没有它们你的mod连加载入口都找不到。

安装方式很简单:在Steam的杀戮尖塔商店页面进创意工坊,搜索Basemod、ModTheSpire、stslib,分别点订阅。订阅后Steam会自动把这些mod下载到游戏库里,默认位置是steamapps/workshop/content/646570/目录下,646570就是杀戮尖塔在创意工坊的应用ID。三个支持库各自对应一个子目录,里面就是jar文件。这个路径后面在pom.xml里会用到,最好现在就去硬盘上确认一下这几个jar存在。

注意:不装这三样,不只是没法开发mod,连运行别人做的mod都不行。所以哪怕你只想玩别人的mod,这套订阅步骤也省不掉。

订阅完成后再看游戏本体安装目录,steamapps/common/SlayTheSpire/下会有一个desktop-1.0.jar,这是游戏主jar,编译mod时必须引用它。到这里,开发阶段需要的三个jar就齐了:一个游戏本体,两个支持库。

2.2 IntelliJ IDEA社区版:为什么推荐这种IDE方案

杀戮尖塔是典型的Java面向对象工程,手写代码不是不行,但调试和构建体验会很差。主流的Java IDE是Eclipse和IntelliJ IDEA(下文简称IJ),我推荐用IJ社区版,免费,对Maven的支持也更顺滑。

安装本身没有坑,从官网下载社区版安装包,一路Next装完。需要特别提醒的是:如果你电脑上已经装了其他版本的Java,装完IJ后最好确认一下默认JDK版本。杀戮尖塔本体基于Java 8编译,开发mod时建议把编译器级别固定在1.8,这个后面在pom.xml里会用到。很多报错「不支持的class版本」的人,都是因为本地默认JDK太新,编译出来的字节码游戏加载不了。

2.3 Maven环境变量:MAVEN_HOME和Path到底怎么配

Maven是Java项目的构建工具,负责把代码和依赖打包成jar。它的配置步骤在Windows下其实只有两步:解压、配环境变量。

先去Maven官网下载最新版,解压到一个路径里,比如E:\Maven\apache-maven-3.3.9。注意目录结构,确保E:\Maven\apache-maven-3.3.9\bin这个路径真实存在,后面环境变量指向的就是这一级。然后打开系统属性面板:计算机(或此电脑)右键→属性→高级系统设置→环境变量,做两件事:

# 1. 新建系统变量 MAVEN_HOME = E:\Maven\apache-maven-3.3.9 # 2. 编辑系统变量 Path,新增一行 %MAVEN_HOME%\bin

配完环境变量后,必须新开一个命令行窗口(旧窗口不会刷新环境变量),输入mvn -v验证。能看到Maven版本号、Java版本这些信息,才算配置成功。这里有两个很容易踩的细节:第一,MAVEN_HOME的值不要以反斜杠结尾,E:\Maven\apache-maven-3.3.9\这种写法偶尔会导致后续命令拼接路径时出现双反斜杠;第二,Path中新增的是%MAVEN_HOME%\bin,不是在Path末尾直接粘E:\Maven\apache-maven-3.3.9\bin,虽然两种写法效果一样,但用变量的好处是以后升级Maven只改MAVEN_HOME一处就行。

如果你用IJ做开发,其实IJ自带了Maven插件,不配置系统环境变量也能跑构建。但命令行Maven还是要配好,因为pom.xml出问题时,用mvn clean package在命令行复现报错,信息比IDEA日志更直白,排查效率高很多。

3. 构建首个Mod工程:pom.xml与ModTheSpire.json的完整配置

3.1 新建Maven项目:目录结构与test文件夹的作用

以IJ为例,打开IDEA后选New Project,左侧选Maven,注意Create from archetype那个勾选框不要选,留空直接生成。填项目名和存放地址,我习惯用tutorial作为示例工程名,groupId写成org.example。这个groupId只是个组织标识,不影响最终jar内容,但artifact(也就是artifactId)会直接影响输出jar名,后面finalName还会再覆盖一次。

新建完成后,左侧项目结构里会出现几个关键目录:.idea是IJ的辅助配置,与mod本身无关,不用管;src/main/java是你写代码的地方;src/main/resources放资源文件,比如卡面图片、特效贴图,以及后面要写的ModTheSpire.json;src/test/java是Maven自动生成的测试目录,初学者一般用不到,但不要删,Maven构建流程会默认扫描它。很多第一次接触Maven的人看到src/test目录以为是自己建错了,其实这是Maven的标准结构,删了反而可能在package时报错。

3.2 pom.xml核心:steam.path、dependencies与system scope

pom.xml是Maven工程的配置文件,决定这个项目怎么编译、依赖哪些jar、输出到哪里。打开项目根目录下的pom.xml,按下面的内容改:

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>tutorial</artifactId> <version>0.1</version> <packaging>jar</packaging> <name>tutorialMod</name> <description>tutorial</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <steam.path>E:\SteamLibrary\steamapps</steam.path> </properties> <dependencies> <dependency> <groupId>bin</groupId> <artifactId>BaseMod</artifactId> <scope>system</scope> <version>1.0</version> <systemPath>${steam.path}/workshop/content/646570/1605833019/BaseMod.jar</systemPath> </dependency> <dependency> <groupId>bin</groupId> <artifactId>SlayTheSpire</artifactId> <scope>system</scope> <version>1.0</version> <systemPath>${steam.path}/common/SlayTheSpire/desktop-1.0.jar</systemPath> </dependency> <dependency> <groupId>bin</groupId> <artifactId>ModTheSpire</artifactId> <scope>system</scope> <version>1.0</version> <systemPath>${steam.path}/workshop/content/646570/1605060445/ModTheSpire.jar</systemPath> </dependency> </dependencies> </project>

这段配置里有几个关键点需要理解:

steam.path属性指向的是steamapps目录,不是你SteamLibrary根目录。示例中我填的是E:\SteamLibrary\steamapps,如果你的游戏库在其他盘或路径,只改这一处。后面所有systemPath都是基于这个属性拼接的,所以这个值错了,三个依赖会同时失效。

三个dependency都用了scope=system,意思是「这个jar不走Maven中央仓库,直接引用本地绝对路径」。这是mod开发最常见的做法,因为游戏本体jar和mod支持库谁也不会发布到Maven仓库里,只能手动指路径。systemPath里的数字目录(1605833019、1605060445)是Steam创意工坊分配给具体订阅项的ID,如果你订阅Basemod和ModTheSpire的版本不同,这个数字可能不一样,去实际目录看一眼确认即可。

改完pom.xml后,IDEA右下角会提示Maven配置发生更改,点Import Changes让IDEA重新加载依赖。这一步别忽略,不加载的话后面写代码时import会全部标红。

3.3 装配插件:maven-antrun-plugin自动拷贝jar到mods目录

只有依赖配置还不够,还需要告诉Maven两件事:用哪个Java版本编译、编译完jar之后放哪里。继续在pom.xml里补上build节点:

<build> <finalName>tutorialMod</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <phase>package</phase> <configuration> <target> <copy file="target/tutorialMod.jar" tofile="${steam.path}/common/SlayTheSpire/mods/tutorialMod.jar" /> </target> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> </plugins> </build>

finalName决定输出jar的文件名。如果不设置,Maven默认会输出成tutorial-0.1.jar这种带版本号的格式,finalName可以强制输出为tutorialMod.jar,和后面antrun插件拷贝时定义的文件名保持一致。maven-compiler-plugin里的source和target都设成1.8,这保证编译产物能被游戏本体正常加载,如果你机器上的JDK是17或更高,这两个值帮助你编译出1.8字节码,但前提是代码里别用太新的语法特性。

maven-antrun-plugin的作用是在package阶段完成后执行一段额外的文件操作。我用的是copy任务,把刚构建出来的target/tutorialMod.jar直接复制到游戏的mods目录。杀戮尖塔的mod加载器只扫描SlayTheSpire/mods/目录,所以这一步其实是变相帮你省了「手动把jar丢进mods文件夹」这个操作。注意拷贝目标路径也是基于${steam.path}拼接的,如果前面steam.path配错了,会出现构建成功但mods目录里根本没有文件的诡异情况。

3.4 ModTheSpire.json:modid、dependencies与编码

jar只是代码的载体,ModTheSpire加载一个mod时还要读取一个标识文件——ModTheSpire.json,它告诉加载器这个mod叫什么、作者是谁、依赖什么。在src/main/resources目录下新建文件,命名为ModTheSpire.json(区分大小写,别写错),内容如下:

{ "modid": "tutorial", "name": "tutorialMod", "author_list": ["A", "B"], "description": "新手教程mod", "version": "0.0.1", "sts_version": "03-29-2018", "mts_version": "2.6.0", "dependencies": ["basemod"] }

各字段含义:modid是mod的唯一标识,全小写,不能有空格;name是显示在ModTheSpire界面里的名字;author_list是作者数组,可以写多人;description是简介,支持中文;version是mod版本号;sts_version和mts_version是游戏本体和ModTheSpire的版本号,用于兼容性校验;dependencies声明依赖的mod,这里写basemod表示本mod依赖Basemod就必须在BaseMod之后加载。

JSON格式的坑主要在大括号和方括号的配对、逗号要不要加。花括号{}代表对象,方括号[]代表数组,author_list和dependencies都是数组,元素之间用逗号分隔但最后一个元素后面不能有逗号。养成写完JSON就检查一遍的习惯,这个文件如果有语法错误,在游戏里表现就是mod直接消失,不会报错。

4. Mod代码骨架:从@SpireInitializer到监听函数

4.1 创建Package和类:@SpireInitializer的初始化流程

现在开始写代码。在src/main/java下新建一个package,命名用mod的小写名称,比如tutorial。package相当于文件夹,作用是组织类文件,避免类名冲突。然后在包里新建一个Java类,类名首字母大写,这里用经典的Tutorial:

package tutorial; import com.evacipated.cardcrawl.modthespire.lib.SpireInitializer; @SpireInitializer public class Tutorial { public Tutorial() { } public static void initialize() { new Tutorial(); } }

这段代码是每个mod的固定入口。@SpireInitializer是ModTheSpire提供的注解,告诉它「这个类里有初始化方法,加载mod时请调用」。initialize()必须是public static void,方法内部调用构造函数创建一个Tutorial对象,这个对象会作为mod实例被ModTheSpire持有。

很多人不理解为什么Module初始化要拐这么个弯,不能直接在initialize里写功能吗?可以,但后面做监听时要在构造函数里执行BaseMod.subscribe(this)完成事件订阅,所以构造函数是必留的。

4.2 控制台输出与基础变量:调试的第一个工具

Mod开发里最重要的调试手段就是往ModTheSpire的log控制台打输出。游戏加载mod时或运行中,ModTheSpire会有一个独立的log窗口,系统的System.out输出都会打到那里。在initialize方法里加一行:

System.out.print("hello world!");

System.out.print是Java最基础的输出语句,括号里的内容会原样打印到控制台。注意字符串要用半角双引号包裹,语句以分号结尾。print不会自动换行,如果想换行要用println,或者手动加\n转义字符。常见的组合写法是:

System.out.print("hello world! 5*6+30="); System.out.print(5 * 6 + 30); System.out.print("end of line!\n2+2=" + 4); // 这里+号表示字符串拼接

第一个print输出固定文本,第二个print直接输出表达式计算结果(60),第三个print演示转义和字符串拼接。这里的+在字符串上下文中是连接符,不是数学加法;\n是换行符,它不代表字符n。这套输出方法在验证mod是否加载成功、调试数值计算时非常实用。

变量方面,mod开发最常用的是四种:int整型、float浮点型、boolean布尔型、String字符串型。声明变量由四部分组成——属性、类型、名称、初始化值:

public int number; private float dot = 2.4f; public static boolean judge = true; public final String HELLO = "Hello world!";

public和private控制访问范围,static表示这个变量属于类而不是某个对象(所有对象共享),final表示常量,赋值后不能修改。float的数值后面要加f后缀,不加会默认为double类型。String的初始化用双引号,常量命名全部大写并用下划线分隔。

4.3 监听函数:BaseMod.subscribe与接口实现

mod的核心能力是响应游戏内的事件。Basemod提供了一套订阅机制:游戏触发某个动作时,通知所有订阅了该事件的对象。具体做法是让你的类实现一个接口,并在构造函数里调BaseMod.subscribe(this)。下面是一个实战例子,监听「玩家抽牌」事件,并把抽到的牌名打到log里:

package tutorial; import basemod.BaseMod; import basemod.interfaces.PostDrawSubscriber; import com.evacipated.cardcrawl.modthespire.lib.SpireInitializer; import com.megacrit.cardcrawl.cards.AbstractCard; @SpireInitializer public class Tutorial implements PostDrawSubscriber { public Tutorial() { BaseMod.subscribe(this); } public static void initialize() { new Tutorial(); } @Override public void receivePostDraw(AbstractCard abstractCard) { System.out.println(abstractCard.name); } }

接口名PostDrawSubscriber以Subscriber结尾,对应游戏里「抽牌后」这个动作。实现它必须重写receivePostDraw方法,方法的形参AbstractCard abstractCard就是刚抽到的那张牌对象,通过abstractCard.name能拿到它的显示名称。@Override注解表示这是重写父接口的方法,写错方法名时IDE会直接报错,相当于帮你检查拼写。调试时这个方法很直观——你抽一张牌,log就多一行牌名。再看一个监听玩家受伤的例子:

package tutorial; import basemod.BaseMod; import basemod.interfaces.OnPlayerDamagedSubscriber; import com.evacipated.cardcrawl.modthespire.lib.SpireInitializer; import com.megacrit.cardcrawl.cards.DamageInfo; @SpireInitializer public class Tutorial implements OnPlayerDamagedSubscriber { public Tutorial() { BaseMod.subscribe(this); } public static void initialize() { new Tutorial(); } @Override public int receiveOnPlayerDamaged(int damage, DamageInfo damageInfo) { return damage; } }

receiveOnPlayerDamaged会在玩家受到伤害时被调用,形参damage是伤害数值,damageInfo携带伤害来源信息。注意这个方法有返回值int,意味着你可以在这里修改受到的伤害——比如实现减伤效果,把damage改成damage / 2再返回。mod里修改游戏数值的玩法,本质上都是靠这类带返回值的监听函数在游戏计算路径中间插入一段自己的逻辑。

4.4 引用与继承:如何理解对象传递和类继承

Java中的一个经典困惑:为什么调用swap(a, b)交换函数后,原来的a、b数值没变?原因在于基本类型按值传递,函数里拿到的只是副本。这里不展开理论,直接给结论:int、float、boolean这类基本变量进函数是复制一份,在函数里怎么改都不影响外面;但对象不一样,比如前面监听函数里abstractCard.name = "NULL"这样改,外面那张牌的名字真的会变。

原因在对象声明方式上:

A a = new A();

new A()真正创建了对象,a不是对象本身,而是对象的引用。引用就像替身或快捷方式,传给函数时复制的是「指向同一个对象的入口」,所以函数里通过引用修改的字段,原对象也变了。理解这一点,就能解释为什么监听函数能改游戏对象的状态,而普通的int参数传进函数里却改动无效。Java提供了基本类型的封装类,比如Integer对应int、Boolean对应boolean,把基本变量也包装成对象,这样在泛型和某些框架场景里能用统一的引用方式处理。

继承则是mod开发中处理「多个相似事物公共逻辑」的手段。机器人职业有多种能量球,它们都有「被激发」「每回合执行操作」这些共性,但如果每个球类都单独写一遍,代码就冗余了。正确做法是先建一个父类描述共性,然后让具体球类继承它,子类各自补充差异。杀戮尖塔自带的大量卡牌和角色逻辑也用同样的设计思路,写mod时经常会继承AbstractCard、AbstractPower这些类来定义自己的新卡和新能力,掌握继承才能读懂游戏本体源码。

5. 常见问题与排查:加载失败、编译报错和编码坑的修复

5.1 jar没进mods目录:steam.path的路径错位

现象:Maven构建成功,控制台一路BUILD SUCCESS,但打开游戏mods目录,里面什么都没有,或者ModTheSpire界面看不到自己的mod。

原因:绝大多数情况下是steam.path属性配错了。注意steam.path要指向steamapps这一层,而不是SteamLibrary根目录。很多人抄到配pom时将steam.path写成了E:\SteamLibrary,于是antrun的copy目标拼出来是E:\SteamLibrary\common\SlayTheSpire\mods,这个路径在磁盘上根本不存在(正确路径是E:\SteamLibrary\steamapps\common\SlayTheSpire\mods),Maven的copy任务不会因为目标目录不存在而报错,它只是默默复制失败。

解决:先手动打开资源管理器,确认steamapps\common\SlayTheSpire\mods目录是否存在,不存在就新建一个。然后回pom.xml核对steam.path值,重跑mvn clean package,构建完成后用文件夹直接检查SlayTheSpire\mods\tutorialMod.jar的最后修改时间。这个排查顺序比在游戏里反复开关效率高得多。

5.2 ModTheSpire界面看不见mod:json字段与依赖声明

现象:jar文件确实在mods目录里,但打开ModTheSpire的mod选择界面,列表里就是没有你的mod。

原因:ModTheSpire加载时会对jar内的ModTheSpire.json做严格校验。最常见的是modid重复——创意工坊或本地已有的其他mod占用了相同modid;其次是dependencies声明有问题,比如你声明了["basemod"]但界面里没勾选Basemod,加载器会认为依赖缺失而跳过;再有就是JSON格式错误,多一个逗号或少一个引号都会让整个mod被静默丢弃。

解决:在ModTheSpire启动时观察log窗口,加载失败的mod会把具体原因打印出来。改modid为全局唯一值,检查JSON语法兼容性,然后确认游戏启动时的mod列表里,Basemod和你的mod前的勾选框都打上了。注意modid不能带大写字母和连字符,tutorial_mod这种写法也可能触发校验问题。

5.3 编译找不到游戏类:依赖jar的systemPath失效

现象:IDEA里写import com.megacrit.cardcrawl.cards.AbstractCard;后整行标红,报「程序包com.megacrit.cardcrawl不存在」,或者Maven构建时报错无法从systemPath读取jar。

原因:pom.xml里三个jar的systemPath指向的路径不存在,或者路径中包含非ASCII字符、空格未正确转义。还有一种情况:steam.path属性中如果使用反斜杠\,在XML解析时反斜杠本身没有转义问题,但如果你在Windows路径里用了中文目录名,Maven的路径处理偶尔会出幺蛾子。

解决:先去文件管理器逐层核对systemPath拼出来的完整路径,确认jar真实存在。如果IDEA标红但路径没问题,点一下Maven工具窗口的刷新按钮(Reload All Maven Projects),让IDEA重新读取依赖。我的习惯是用属性拼接路径时,先展开写一遍完整的绝对路径,确认无误后再改回${steam.path}格式,这样能快速区分是属性值错还是拼写错。

5.4 中文乱码与版本不匹配:编码、mts_version的坑

现象:游戏内mod名称或卡牌描述显示成乱码,或者mod加载时提示sts_version/mts_version不匹配。

原因:乱码是因为保存编码不一致。pom.xml里虽然设置了project.build.sourceEncoding=UTF-8,但你编辑ModTheSpire.json或Java文件时,IDE右下角显示的编码如果是GBK,保存后就会以GBK编码写入;日志报版本不匹配则是因为json里的mts_version和当前装的ModTheSpire实际版本号对不上——教程示例里的2.6.0是旧版本,你现在装的很可能是更新版本。

解决:全工程强制设为UTF-8。在IDEA设置里把File Encodings的三项(Global Encoding、Project Encoding、Properties Files)都改成UTF-8,已有文件如果已经乱码只能重新编辑一遍。版本号则打开ModTheSpire的jar包里的META-INF/MANIFEST.MF或用压缩工具查看版本信息,把json里的mts_version改成实际版本。一个非常实用的小技巧:把空的sts_version和mts_version先清掉再填,如果加载还是报不匹配,就去ModTheSpire目录翻它的config文件,等号后面的值就是加载器期望的版本写法的参考。

6. 装完验证跑通:看log、勾mod、跑一次package全链路

环境配好、工程搭好后,最后一步是把整个链路真正跑通一次,而验证方式不能只是「构建成功了」——构建成功只代表Maven配置对了,不代表游戏能加载你的mod。我的验证流程固定按以下五步走,每一步出问题都能定位到具体环节。

第一步,命令行验证Maven环境:新开一个终端,执行mvn clean package,注意这里有两个动作,clean负责清掉上次构建的残留,避免旧jar混进来。

第二步,检查构建产物和拷贝结果:看target目录下有没有tutorialMod.jar,再看游戏目录SlayTheSpire\mods\tutorialMod.jar是否同步生成。这一步过了,说明pom.xml里的依赖和插件链路没问题。

第三步,用带ModTheSpire的方式启动游戏。在Steam里对杀戮尖塔设置启动项为--with-mod-the-spire,或者直接运行ModTheSpire的启动器。启动后ModTheSpire会先弹出一个mod选择界面,这个界面就是加载器扫描所有可用mod的展示窗口。在这里勾选Basemod和你的tutorialMod,再点Play进入游戏。

第四步,观察ModTheSpire的log窗口。如果一切正常,你会看到模组初始化时打印的hello world!,以及类似2ms这样一行「mod加载耗时」输出。这一步是验证mod代码真正被游戏进程执行了的铁证。如果没看到输出,回去检查@SpireInitializer注解是否拼对、类是不是public。

第五步,进游戏里做功能验证。如果只是验证环境跑通,可以在战斗中抽几张牌,看log窗口里是否出现卡牌名字——这是最直观的监听函数生效证明。如果你跟着作业走到了监听函数章节,可以把玩家受伤监听和战斗结束监听组合起来,在receivePostBattle里打印本场战斗累计受到的伤害总和,这个功能会把环境验证和代码能力一起考了。

从那以后我每次搭新的mod工程,都强制自己先跑一遍这套「构建→查目录→看log→游戏内触发事件」的全链路,确认每个环节都通才写正式功能。环境问题当场解决,后面的开发会顺很多;如果log里有任何一行报错,也一定当场处理掉再继续,因为很多玄学问题拖到后面排查会更花时间。希望这篇环境落地的笔记能帮到你,让第一个mod尽早跑起来。

本文还有配套的精品资源,点击获取