Starsector Nihilism Guidance
首页
GitHub 项目
首页
GitHub 项目
  • 首页
  • 基础及舰船相关
    • MOD 骨架和入口文件
    • 制作一艘基本舰船
    • 制作一艘航母与战机
    • 制作一艘相位舰
    • 制作火炮、光束与导弹
    • 为舰船加入内置武器、船插与战机
    • 补充描述文本
  • 无需入门的代码修改
    • 以船插为例初步熟悉代码
    • 制作完整船插
    • 制作最小战术系统
    • 为武器加入命中与光束特效
  • 势力与生涯星系
    • 注册一个势力
    • 配置势力舰队
    • 制作 MOD 入口类的最基础适配
    • 制作一个生涯星系
    • 补完描述文本
  • 战役与无代码对象
    • 制作测试战役装配
    • 为模拟战与标题画面加入装配
    • 为舰船加入外观风格
    • 制作一艘模块船
    • 制作一种星体类型
    • 制作一个自定义实体
  • 音频资源与播放
    • 准备 OGG 音频资源
    • 注册音频资源
    • 为游戏对象加入音频
  • Java 工程化
    • 确认 Java 与编译依赖
    • 迁移代码文件到 src
    • 配置 Gradle 工程
    • 构建 JAR 并声明产物
  • 全局服务
    • 制作 MOD 入口类
    • 使用 Global 访问游戏服务
    • 读取设置
    • 调用声音播放器
    • 记录和定位 MOD 日志
  • 战斗运行时
    • 读取战斗引擎状态
    • 读取战斗对象
    • 制作每帧战斗插件
    • 修改舰船数值
    • 配置武器脚本
    • 配置战斗监听器
    • 制作分层渲染插件
  • 战斗内容扩展
    • 详解舰船插件
    • 详解战术系统
    • 详解武器动画
  • 生涯世界与基础服务
    • 读取生涯世界状态
    • 构建生涯地点
    • 配置生涯势力
    • 放置生涯实体
  • 生涯舰队与舰队成员
    • 生成生涯舰队
    • 管理舰队中的成员
    • 舰队状态的重算过程
    • 维护舰队成员状态
    • 读取并修改舰船装配
  • 市场与商品
    • 创建生涯市场
    • 读写货舱内容
    • 注册市场商品
    • 实现专用子市场
    • 制作专用产业
    • 注册特殊物品
    • 实现市场条件
  • 人物与技能
    • 配置人物基础
    • 让人物承担角色
    • 制作角色技能
  • 生涯脚本与情报事件
    • 编写生涯逐帧脚本
    • 监听生涯事件
    • 选择生涯插件
    • 管理舰队活动情报
  • 酒吧事件与任务
    • 组织生涯交互对话
    • 实现对话插件
    • 接入酒吧事件
    • 构建阶段任务
    • 接入酒吧任务
  • Rules 系统、命令与内存
    • 组织 Rules 规则表
    • 编排 Rules 对话
    • 接入 Rules 生涯场景
    • 编写 Rules 命令
    • 使用 MemoryAPI 保存状态
  • 文件读取与写入
    • 读取 MOD 内文本
    • 读取 MOD 内 JSON 文件
    • 读取 MOD 内 CSV
    • 读写 common 数据
    • 实现本地化机制
  • 常用依赖库
    • 接入常用依赖库
    • 使用 LazyLib 几何工具
    • 使用 LazyLib 查询战场
    • 使用 LazyLib 保存公共 JSON
    • 注册 GraphicsLib 光照数据
    • 创建 GraphicsLib 动态光源
    • 制作 GraphicsLib 纹理映射
    • 配置 MagicLib 自动尾迹
    • 创建 MagicLib 运行时尾迹
    • 配置 MagicLib 数据赏金
    • 使用 MagicLib 辅助生涯开发
    • 使用 MagicLib 战斗小工具
  • 可选依赖与 Nexerelin
    • 接入可选依赖
    • 登记 Nexerelin 势力与外交配置
    • 配置 Nexerelin 的两种星区开局
    • 配置 Nexerelin 战略 AI 与扩张规模
    • 登记 Nexerelin 地面战单位与产业
    • 为 Nexerelin 特遣队添加命名与事件响应
    • 制作即时生效的 LunaLib 设置面板
  • 着色器与渲染
    • 使用 Java OpenGL
    • 使用 GLSL 进阶
    • 使用 VBO 和 VAO 保存顶点
    • 使用 SSBO 传递参数
    • 使用实例化进行绘制
    • 选择 BoxUtil 渲染方案

制作一个生涯星系

势力已经注册,入口类也能在新档中执行代码。本节继续通过这个入口生成 GearIn 星系:放入恒星、两颗行星和通讯中继,给主行星建立基础市场,再生成超空间入口。原版已经提供这些对象的类型,我们主要决定名称、位置与归属。

本节预期阅读时间:~14 分钟。

本节预期操作时间:~15 分钟。

学习目标

完成后,您将能够:

  • 从新档回调调用星系生成器;
  • 放置恒星、行星、通讯中继与跳跃点;
  • 区分创建星系、创建实体与加入实体的操作;
  • 给主行星绑定基础市场、产业与子市场;
  • 在星图、轨道、交互和交易界面核对生成结果。

前置知识

  • [C3-S1] 的 gear_industry 势力;
  • [C3-S3] 的 GearInModPlugin 与新档回调;
  • [C2-S1] 的 Java 文件、包名与类名对应关系;
  • 能够在生涯星图中定位星系、通过跳跃点移动并与行星交互。

创建星系生成器并接入入口

创建 data/scripts/gearin/campaign/GearInSystemGenerator.java。这个类采用 SectorGeneratorPlugin 的生成器结构,操作都写在 generate(SectorAPI sector) 方法中,完整文件在后面给出。

回到上一节的 GearInModPlugin.java,在 import 区加入:

import data.scripts.gearin.campaign.GearInSystemGenerator;

再把新档回调改为下面的局部片段:

@Override
public void onNewGame() {
    new GearInSystemGenerator().generate(Global.getSector());
    seedRelations(Global.getSector());
}

第一条语句创建生成器并调用 generate,第二条继续设置关系。mod_info.json 的入口值仍指向 GearInModPlugin。生成器由入口主动调用,因此保存生成器类文件后,还要在入口中保留这条调用。

接下来依次向 generate 中加入代码。每段创建的对象会供后面的操作使用,因此按当前顺序排列。

建立星系、恒星与超空间位置

先创建星系容器:

StarSystemAPI system = sector.createStarSystem("GearIn");
system.setBackgroundTextureFilename("graphics/backgrounds/background2.jpg");
system.setLightColor(new Color(200, 200, 210));

system 保存刚创建的星系,背景路径和光照颜色采用原版资源。之后的行星、实体和入口都加入这个 system,让它们属于同一个地点。

再初始化恒星并设置超空间位置:

PlanetAPI star = system.initStar("gearin", "star_yellow", 600f, 550f, 3f, 0.75f, 1f);
system.getLocation().set(-16000f, -9000f);

gearin 是恒星 ID,star_yellow 是原版黄色恒星类型。star 保存创建得到的恒星,行星和通讯中继随后以它作为轨道焦点,因此这一步放在行星创建之前。

initStar 参数速查表

参数当前填写
恒星 IDgearin
恒星类型star_yellow
恒星半径600
日冕范围550
恒星风移动影响3
耀斑概率0.75
日冕 CR 损耗倍率1

星系内部的轨道位置与星系在超空间中的位置分别设置。 system.getLocation().set(...) 使用超空间坐标,本例选取 (-16000,-9000)。它决定 GearIn 在星图中的位置,调整时可以先以原版核心区作为参照,再留出希望的航程。

恒星初始化也会按恒星 ID 查询 data/campaign/starmap.json 中的 starSystemLocations。本例直接写超空间坐标;采用数据表定位时,登记 gearin 对应的位置即可。

放置两颗行星

在恒星之后添加主行星与外侧行星:

PlanetAPI prime = system.addPlanet(
        "GearIn_planet1", star, "GearIn Prime",
        "terran", 55, 150, 3200, 120);
PlanetAPI second = system.addPlanet(
        "GearIn_planet2", star, "GearIn Second",
        "barren", 200, 90, 5200, 200);

GearIn_planet1、GearIn_planet2 是实体 ID,Prime 与 Second 是显示名。第二个参数 star 指定轨道焦点,terran 和 barren 则选择原版行星类型。

addPlanet 后四个数字依次为轨道角、行星半径、轨道半径和轨道周期天数。主行星半径为 150,轨道半径为 3200,周期为 120 天;外侧行星半径 90,轨道半径 5200,周期 200 天。轨道焦点与轨道参数共同确定行星的位置关系,可以按代码中的对象与数值核对星图。

addPlanet 同时把行星加入当前星系。它返回的对象分别保存在 prime 与 second 中,后面的市场、描述等配置继续使用这两个引用。

加入原版通讯中继

在同一个 system 中添加中继:

SectorEntityToken stable = system.addCustomEntity(
        "GearIn_stable", "GearIn 通讯中继",
        "comm_relay", "gear_industry");
stable.setCircularOrbitPointingDown(star, 90, 2200, 100);

comm_relay 是原版实体类型,gear_industry 指定所属势力。返回的中继实体保存在 stable 中,随后通过它设置围绕恒星的轨道,仍然使用刚才的 star 作为焦点。

轨道角为 90,半径为 2200,周期为 100 天,PointingDown 采用该类实体常用的朝向方式。原版实体类型可以直接用于本节制作,自定义类型则由 [C4-S6] 展开。

给主行星建立基础市场

行星的外观类型与它的市场分别配置,terran 类型本身不会完成这里的市场创建。本节给 Prime 创建规模 4 的市场,使用人口、太空港、公开市场和仓储这些原版组件。

先建立市场与行星的归属,局部片段如下:

MarketAPI market = Global.getFactory().createMarket(prime.getId(), prime.getName(), 4);
market.setFactionId("gear_industry");
market.setPrimaryEntity(prime);
market.setSurveyLevel(MarketAPI.SurveyLevel.FULL);

createMarket 使用行星 ID、名称与规模,创建得到的市场保存在 market 中。setPrimaryEntity 将 Prime 指定为主实体,FULL 把勘测状态设为已完成。归属关系设置后,再添加市场内容:

market.addCondition("population_4");
market.addIndustry("population");
market.addIndustry("spaceport");
market.addSubmarket("open_market");
market.addSubmarket("storage");

这些字符串都是原版已注册的 ID,分别写入市场的条件、产业与子市场。市场条件描述规模 4 的人口,产业提供人口与太空港,子市场提供公开交易与仓储。

最后把它加入星区经济,并连接回行星:

sector.getEconomy().addMarket(market, true);
prime.setMarket(market);
prime.setFaction("gear_industry");

创建市场、加入经济与绑定实体都要完成。 使用行星的 ID 和名称创建市场之后,仍要通过上面的调用建立实际连接。完成后,玩家靠近 Prime 就可以打开对应市场。当前配置用于验证交易与归属,市场的完整行为与自定义商品由 [C12-S1]、[C12-S3] 继续讲解。

生成往返星系的入口

创建跳跃点并设置轨道:

JumpPointAPI jump = Global.getFactory().createJumpPoint("GearIn_jump", "GearIn 跳跃点");
jump.setCircularOrbit(star, 300, 1800, 100);
jump.setRelatedPlanet(prime);
system.addEntity(jump);
system.autogenerateHyperspaceJumpPoints(true, true);

createJumpPoint 先返回跳跃点对象,system.addEntity(jump) 再把它加入星系。与前面的 addPlanet、addCustomEntity 相比,这个创建方法需要单独完成加入操作。

autogenerateHyperspaceJumpPoints 根据星系内部的入口生成超空间端,并连接目的地。两个 true 分别允许生成气态巨行星入口与边缘跳跃点。在调整星系时,入口位置也属于设计的一部分:玩家抵达后还需要从这里驶向行星,轨道间距直接影响这段航程。

完整最小例

入口类保存到 data/scripts/gearin/GearInModPlugin.java,生成器保存到 data/scripts/gearin/campaign/GearInSystemGenerator.java。入口声明继续采用 [C3-S3] 的完整类名。

完整成品:GearInModPlugin
package data.scripts.gearin;

import com.fs.starfarer.api.BaseModPlugin;
import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.campaign.FactionAPI;
import com.fs.starfarer.api.campaign.RepLevel;
import com.fs.starfarer.api.campaign.SectorAPI;

import data.scripts.gearin.campaign.GearInSystemGenerator;

/** 在新档生成时建立齿轮工业星系与初始关系。 */
public class GearInModPlugin extends BaseModPlugin {

    @Override
    public void onNewGame() {
        new GearInSystemGenerator().generate(Global.getSector());
        seedRelations(Global.getSector());
    }

    private void seedRelations(SectorAPI sector) {
        FactionAPI gear = sector.getFaction("gear_industry");
        gear.setRelationship("player", 0f);
        gear.setRelationship("pirates", RepLevel.HOSTILE);
        gear.setRelationship("hegemony", RepLevel.FRIENDLY);
        gear.setRelationship("tritachyon", RepLevel.HOSTILE);
    }
}
完整成品:GearInSystemGenerator
package data.scripts.gearin.campaign;

import java.awt.Color;

import com.fs.starfarer.api.Global;
import com.fs.starfarer.api.campaign.JumpPointAPI;
import com.fs.starfarer.api.campaign.PlanetAPI;
import com.fs.starfarer.api.campaign.SectorAPI;
import com.fs.starfarer.api.campaign.SectorEntityToken;
import com.fs.starfarer.api.campaign.SectorGeneratorPlugin;
import com.fs.starfarer.api.campaign.StarSystemAPI;
import com.fs.starfarer.api.campaign.econ.MarketAPI;

/** 创建包含两颗行星、通讯中继、基础市场与跳跃点的齿轮工业星系。 */
public class GearInSystemGenerator implements SectorGeneratorPlugin {

    @Override
    public void generate(SectorAPI sector) {
        StarSystemAPI system = sector.createStarSystem("GearIn");
        system.setBackgroundTextureFilename("graphics/backgrounds/background2.jpg");
        system.setLightColor(new Color(200, 200, 210));

        PlanetAPI star = system.initStar("gearin", "star_yellow", 600f, 550f, 3f, 0.75f, 1f);
        system.getLocation().set(-16000f, -9000f);

        PlanetAPI prime = system.addPlanet(
                "GearIn_planet1", star, "GearIn Prime", "terran", 55, 150, 3200, 120);
        PlanetAPI second = system.addPlanet(
                "GearIn_planet2", star, "GearIn Second", "barren", 200, 90, 5200, 200);

        SectorEntityToken stable = system.addCustomEntity(
                "GearIn_stable", "GearIn 通讯中继", "comm_relay", "gear_industry");
        stable.setCircularOrbitPointingDown(star, 90, 2200, 100);

        MarketAPI market = Global.getFactory().createMarket(prime.getId(), prime.getName(), 4);
        market.setFactionId("gear_industry");
        market.setPrimaryEntity(prime);
        market.setSurveyLevel(MarketAPI.SurveyLevel.FULL);
        market.addCondition("population_4");
        market.addIndustry("population");
        market.addIndustry("spaceport");
        market.addSubmarket("open_market");
        market.addSubmarket("storage");
        sector.getEconomy().addMarket(market, true);
        prime.setMarket(market);
        prime.setFaction("gear_industry");

        JumpPointAPI jump = Global.getFactory().createJumpPoint("GearIn_jump", "GearIn 跳跃点");
        jump.setCircularOrbit(star, 300, 1800, 100);
        jump.setRelatedPlanet(prime);
        system.addEntity(jump);
        system.autogenerateHyperspaceJumpPoints(true, true);
    }
}

验证方案

  1. 保存入口和生成器,重启游戏,确认 modPlugin 指向 data.scripts.gearin.GearInModPlugin,创建新生涯。
  2. 在星图定位 GearIn,从超空间入口进入,核对黄色恒星、Prime、Second 和通讯中继。
  3. 查看轨道焦点与相对距离,核对中继归属齿轮工业。
  4. 靠近 Prime,进入公开市场和仓储,观察规模、商品与所属势力。
  5. 返回超空间再进入,确认星系入口与跳跃点连接正常。

预期结果:

  • GearIn 位于设置的超空间坐标,新档中可以进入。
  • 恒星使用 star_yellow,Prime 使用 terran,Second 使用 barren,轨道分别围绕恒星。
  • 中继采用 comm_relay,归属 gear_industry。
  • Prime 的规模 4 市场可以打开公开交易与仓储,勘测状态为已完成。
  • 星系内的手动跳跃点与超空间端连接,玩家可以往返。

故障分析

  • 星系位于超空间原点:位置表缺少恒星 ID,生成器也未写入超空间位置。

    • 解决方案:在恒星初始化后设置 system.getLocation(),或登记 starmap.json 位置,保存后创建新档。
  • 行星或实体没有出现:创建使用了不同星系容器,或跳跃点尚未加入实体集合。

    • 解决方案:核对当前 system,为工厂创建的跳跃点调用 addEntity,重新创建生涯。
  • 新档没有生成星系:入口未加载,或回调未调用生成器。

    • 解决方案:核对入口声明、import 和 generate 调用,重启并创建测试生涯。
  • 行星没有可交易市场:市场未加入经济、主实体未指定或子市场 ID 填错。

    • 解决方案:核对市场创建、经济登记、实体绑定与 open_market、storage,创建新档验证。

总结

本节从新档回调调用生成器,建立星系与实体,再为 Prime 接入基础市场,并生成超空间入口。对象类型来自原版定义,代码提供位置、轨道与归属,各步骤返回的对象用于后续配置。

现在已经有了一个能进入、交互与交易的星系。继续扩充时,沿着同样的对象关系加入内容,再分别核对星图、轨道和交互结果;下一节为势力、系统和行星补上各自的描述。

建议参考项

  • com.fs.starfarer.api.campaign.SectorGeneratorPlugin:生成器的 generate 方法。
  • com.fs.starfarer.api.campaign.SectorAPI:创建星系和取得星区经济。
  • com.fs.starfarer.api.campaign.StarSystemAPI:初始化恒星、放置实体、超空间位置与入口生成。
  • com.fs.starfarer.api.campaign.JumpPointAPI:跳跃点对象与行星关联。
  • com.fs.starfarer.api.campaign.econ.MarketAPI:市场组件、主实体与勘测状态。
  • data/config/planets.json:原版恒星与行星类型。
  • data/config/custom_entities.json:原版生涯实体类型。
  • data/campaign/starmap.json:starSystemLocations 超空间位置数据。
在 GitHub 上编辑此页
上次更新: 2026/10/14 12:25
贡献者: 1847905557
上一页
制作 MOD 入口类的最基础适配
下一页
补完描述文本