
TropicBeltSpacing
模组作者:妙妙在路上 抖音@妙妙在路上 —— 按戴森球计划「回归线分带」自动放大传送带节点间距(省料),每节硬性 ≤ √5.3(2.302 m) 保证原版合法。默认按F9开关功能。自动接管其它类型经纬度长带模组。回归线传送带间距 / Tropic Belt Spacing
模组作者:妙妙在路上 抖音@妙妙在路上 —— 按戴森球计划「回归线分带」自动放大传送带节点间距(省料), 每节硬性 ≤ √5.3(2.302 m) 保证原版合法。默认按 F9 开关功能。自动接管其它类型经纬度长带模组。
戴森球计划(Dyson Sphere Program)BepInEx 5 插件。
本模组完全独立:不需要、也不依赖任何其它模组(包括 LongerBelts)。 单独把 dll 丢进
BepInEx\plugins即可使用;它自己实现节点的抽稀与拆节, 而且对“别人生成的节点表”也会做双向校正(过密抽稀、过稀/超限拆短),所以不挑搭档。
- 按游戏的“回归线”分带自动放大传送带节点间距:赤道侧第一带 1.8 格 → 极区带 1.6 格(可在 cfg 里改),中间各带线性插值, 并且始终把每节传送带的长度钳制在原版合法范围内(≤ √5.3 = 2.302172 m),所以在原版(无 mod)里也能正常重建蓝图。
- 游戏内只有一个开关快捷键 F9(可在 cfg 里改):按下的瞬间屏幕上会弹出提示(已开启/已关闭);本模组没有任何常驻 UI 面板,
所有可调项都在
BepInEx\config\TropicBeltSpacing.cfg里改。
1. 原理
1.1 回归线分带(游戏真实网格)
所有岩质行星的表面网格完全一样,网格疏密变化的界线(游戏内部就叫 tropic / 回归线)在以下纬度(度):
0(赤道) | 28.8 | 46.8 | 55.8 | 64.8 | 70.2 | 75.6 | 79.2 | 82.8 | 84.6 | 86.4 | 88.2 | 90(极点)
相邻两条界线之间是一个“带”,南北半球镜像,共 24 个带。相邻带之间的格数比正是官方开发日志里说的那六种: 1:2、2:3、3:4、4:5、5:6、5:8。本模组按带给出间距,赤道侧最大、越靠近极点越小:
| 带 | 纬度范围 | 默认间距(格) |
|---|---|---|
| 0 | 0° ~ 28.8° | 1.800 |
| 1 | 28.8° ~ 46.8° | 1.782 |
| 2 | 46.8° ~ 55.8° | 1.764 |
| … | … | …(线性插值) |
| 11 | 88.2° ~ 90° | 1.600 |
1 格 = 当地网格格子的边长(赤道 2π × 200 m / 1000 = 1.256637 m),因此赤道带 1.8 格 ≈ 2.262 m, 极区带 1.6 格 ≈ 2.011 m(当地格更小时按当地格换算)。
1.2 原版是怎么判定“最远间距”的
反编译游戏本体 Assembly-CSharp.dll 得到的结论:
| 判定 | 出处 | 条件 | 结果 |
|---|---|---|---|
| 太远 | BuildTool_BlueprintPaste::CheckBuildConditions |
`desc.isBelt && | output.lpos - lpos |
| 太近 | BuildTool_Path::CheckBuildConditions |
与连接点距离 < 0.4 |
EBuildCondition.TooClose(13) |
即:单节传送带的直线长度上限 = √5.3 = 2.302172 m,连接类下限 = 0.4 m。
所以 1.6 ~ 1.8 格(2.011 ~ 2.262 m)天然落在原版合法区间内;本模组还会用
min(配置值, 2.302172) − 0.001 作为硬上限,保证任何星球、任何纬度都不会越界。
1.3 本模组的做法(按目标间距沿原版折线重采样)
先说两个从本体反编译 + 数据表核对得到的事实(v1.0.2 之前我把第 2 条搞错了,导致间距被放大 5 倍):
PlanetGrid.segment = 200(绕赤道 200 个大格 × 1.8° = 360°,来自PlanetAuxData..ctor里的((int)(radius / 4 + 0.1)) * 4);1 小格 = 2π / (segment × 5) = 0.36° = 1.256637 m(赤道)。 本体PlanetGrid.segmentTable(512 项,已解出数据)给出的也是 200 / 400 / 500 这类大格列数: 赤道 = 200 大格 = 1000 小格,与 wiki 的网格表一致。PlanetGrid.CalcLocalGridSize()返回的就是一个当地小格的长度(赤道 1.2566 m),不是 1/5 格。
原版 PlanetGrid.SnapLineNonAlloc 生成的节点间距就是 1 小格 ≈ 1.2566 m(纬度方向每步 0.99 小格、
经度方向每步 0.6 小格,再吸附到小格)。因此:
- “只抽稀”做不到 1.6~1.8 格:跳过 1 个节点就是 2 格 = 2.513 m > 原版上限 2.302172 m(非法);
- 必须沿原版折线按目标弧长重新采样,节点可以不在网格点上 ——
LongerBelts放大间距用的也是这个思路。
本模组的流程:
- 先让原版算出网格折线(同尺寸缓冲,路径形状与可达长度与原版一致);
- 目标间距 = 该回归线分带的格数(1.6~1.8) × 当地小格长度,钳制在
[0.4, √5.3 − 0.001]m; - 沿折线按目标弧长重采样:球面 Slerp + 高度线性过渡,保留原版拐点(swerve)与首尾节点;
- 末节过短会与前一节合并,任何一节都不会超过
√5.3(原版 TooFar 上限)。
1.4 数值验证
用 C# 复现“原版 1 格节点折线 → 本模组重采样”(segment = 200,1 小格 = 1.256637 m,上限 1.832 格;间距随纬度递减):
band lat 0~12° 目标 1.800 格 = 2.262 m
原版折线(1格节点) : nodes=38 avg=1.271m (1.011格) max=1.280m 非法节=0
本模组重采样 : 每节 = 2.262m (1.800格),max=1.800格 非法节=0
band lat 30~40° 目标 1.782 格 = 2.239 m
本模组重采样 : avg=2.162m (1.721格) max=2.239m (1.782格) 非法节=0
band lat 60~68° 目标 1.745 格 = 2.193 m
本模组重采样 : avg=2.135m (1.699格) max=2.193m (1.745格) 非法节=0
band lat 80~86° 目标 1.655 格 = 2.079 m
本模组重采样 : avg=2.098m (1.669格) max=1.803格 非法节=0
- 每节典型长度 ≈ 目标(1.6~1.75 格),最大 1.79 格 < 1.832 格上限,没有非法节;
- 平均值略低于目标,是因为“接到鼠标端点的最后一节”和拐点处必然有一节稍短(原版同样如此);
- 节点数比原版少约 1/3~2/3 —— 这就是“同样长度、更少的带子”。
1.5 后置补丁兜底(仍然不依赖任何其它模组)
如果前置补丁没跑到(例如别的模组接管了节点生成),PlanetAuxData.SnapLineNonAlloc 的后置补丁
会对现有节点表做同样的重采样:过密就抽稀、过稀就加密、超上限就拆短,最终间距都会被拉回分带目标。
1.6 斜拉走线:原版折弯 + R 键切换
- 本模组不自己发明走线:它拿原版
PlanetGrid.SnapLineNonAlloc生成的网格折线(先经后纬 / 先纬后经两种变体, R 键切换的path参数原样透传),只是沿这条折线按目标弧长重新采样,并强制保留拐点(swerve)节点 —— 所以斜拉时的折弯位置、R 键切换后的走线都与原版一致。 - 如果同时装了会自己生成节点的模组(典型是 LongerBelts 的「更改经纬线模式默认跨度」),
它会绕过原版折线,导致折弯变了、R 键没反应。本模组默认会把这些函数接管回原版网格折线
(
Spacing/UseVanillaGridPath = true,启动日志里会打印“已接管 LongerBelts”), 所以只装本模组就能得到完整功能,不受其它模组影响。
2. 安装
- 游戏已装 BepInEx 5(x64,r2modman 里装 BepInExPack 即可)。
- 把编译产物
TropicBeltSpacing.dll放到:- 游戏本体:
<Dyson Sphere Program>\BepInEx\plugins\TropicBeltSpacing\TropicBeltSpacing.dll - 或 r2modman:
%APPDATA%\r2modmanPlus-local\DysonSphereProgram\profiles\<配置名>\BepInEx\plugins\TropicBeltSpacing\
- 游戏本体:
- 进游戏后按 F9 开关本模组功能(本模组没有游戏内 UI,全部设置改 cfg 文件)。
配置文件:BepInEx\config\TropicBeltSpacing.cfg(cfg 格式,BepInEx 自动生成/保存;
改完保存即可,游戏里按 F9 或重进生效)。
3. 编译
cd TropicBeltSpacing
powershell -ExecutionPolicy Bypass -File .\build.ps1 # 自动找游戏目录和 BepInEx
powershell -ExecutionPolicy Bypass -File .\build.ps1 -Zip # 额外打包 zip
- 不需要联网、不需要 .NET Framework 目标包:脚本用 .NET SDK 自带的 Roslyn
csc, 直接引用游戏DSPGAME_Data\Managed里的 Mono 程序集和 BepInEx 的0Harmony.dll/BepInEx.dll。 - 可用
-GameDir "X:\...\Dyson Sphere Program"和-BepInExCore "X:\...\BepInEx\core"手动指定路径。 - 有 Visual Studio / dotnet + Framework 目标包时,也可以直接用
TropicBeltSpacing.csproj构建。
4. 配置(cfg)说明
| 段 / 键 | 默认 | 说明 |
|---|---|---|
| General / ToggleHotKey | F9 |
游戏内唯一的按键:开关本模组功能。BepInEx 的写法是"最后按下的键写在前面":F9 = 直接按 F9;Alpha4 + LeftAlt = 按住 Alt 再按 4。本模组两种顺序都能识别,但不建议写反。 |
| General / ConfigVersion | 自动 | 配置版本号,程序自动迁移用,不需要手动改 |
| Spacing / Enable | true | 关掉即完全恢复原版间距 |
| Spacing / EquatorBandCells | 1.8 | 赤道带(0°~28.8°)间距,单位:当地格(最大的一档) |
| Spacing / PolarBandCells | 1.6 | 极区带(88.2°~90°)间距,单位:当地格(最小的一档) |
| Spacing / SpacingPerBand | 空 | 可逐带指定,例如 1.8,1.78,1.76,...(赤道带在前,数量需等于带数 12) |
| Spacing / BandLatitudes | 0,28.8,...,90 |
回归线纬度表,一般不用改 |
| Spacing / MaxSegmentMeters | 2.302172 | 单节长度上限,不要改大(超过原版 TooFar,蓝图无法在原版重建) |
| Spacing / MinSegmentMeters | 0.4 | 单节长度下限 |
| Spacing / LogSpacing | false | 验证日志(每秒最多一条,输出带号/目标间距/实测均长)。默认关闭,需要验证模组是否生效时再打开 |
| Spacing / UseVanillaGridPath | true | 斜拉时强制走原版网格折线(折弯 + R 键切换),并接管 LongerBelts 等模组的节点生成 |
| Spacing / BlueprintSafe | false | 默认开启 = 蓝图安全(间距取当地整数格:能 2 格就 2 格,否则 1 格;拐点严格 90°,蓝图可存可复现);关闭 = 自由间距(1.6~1.8 当地格,两条腿等分,但蓝图存不了) |
| Spacing / VerticalThin | true | 垂直抽稀传送带:斜坡带和垂直带都生效。<斜坡带>:沿原版路径按弧长均分抽稀(每节 1.5~1.8 格,等长等爬升、带面不扭曲)。<纯竖直>(X/Y 相同只有 Z 不同):利用游戏「≤1.5 格高度差直接连接」的机制,在后置补丁把高度差均分成 ≤ VerticalThinMaxCells(默认 1.45)格的节,X/Y 完全不变、只有 Z 变化,每一段都被游戏直接连接 → Z 轴抽稀生效 |
| Spacing / VerticalThinMinCells | 1.5 | 垂直抽稀的每节最小长度(当地格) |
| Spacing / VerticalThinMaxCells | 1.45 | 垂直抽稀(Z 轴)的每节最大高度(格)。游戏对 ≤1.5 格的高度差直接连接,不要改到 1.5 及以上 |
| Spacing / SkipClimb | true | 爬坡整条交给原版。只在 VerticalThin=false 时生效 |
| Flatten / Enable | false | 自动拉平总开关(默认关闭:改 tilt/朝向会把竖直带弄歪,垂直抽稀已覆盖爬坡场景) |
| Flatten / ClearTilt | true | 清除 tilt(带面水平,不翻转) |
| Flatten / StraightenVertical | true | 竖直连接时拉直到同一列 + 统一朝向 |
| Flatten / EvenAltitude | false | 竖直带高度按 1.3333 m 层均分(会改变中间高度层,默认关) |
| Flatten / VerticalAngleTolerance | 1.0 | 判定“垂直连接”的角度容差(度) |
| Flatten / VerticalMinHeightCells | 0.5 | 判定“垂直连接”的最小高度差(层,1 层 = 1.3333 m) |
判断标准:路径两端 同一根网格列(经纬度一致、只差高度)且高度差 ≥ 设定层数时,视为“两端垂直连接”, 此时才会做“拉直 + 统一朝向”;否则只清 tilt。拉直时保留各节点自身的高度层(默认),不用手工调高度。
5. 调整方式:只改 cfg 文件
本模组没有游戏内 UI 面板(这样最省性能、也最不容易和别的模组抢输入)。 游戏内只需要按 F9 开关功能;其它任何调整都改这个文件:
BepInEx\config\TropicBeltSpacing.cfg
常用项(完整说明见上一节的表):
| 想做什么 | 改哪个键 |
|---|---|
| 换开关快捷键(默认 F9) | [General 通用] ToggleHotKey |
| 改赤道带 / 极区带间距 | [Spacing 间距] EquatorBandCells / PolarBandCells |
| 逐带精确指定间距 | [Spacing 间距] SpacingPerBand(12 个值,赤道带在前) |
| 需要验证时打开日志(默认关) | [Spacing 间距] LogSpacing = true |
| 爬坡也想省料(可能带面扭曲) | [Spacing 间距] SkipClimb = false(仅当 VerticalThin=false 时有效) |
| 竖直方向交回原版 | [Spacing 间距] SkipVertical = true |
| 垂直抽稀传送带开关(默认开) | [Spacing 间距] VerticalThin = true |
| 垂直抽稀每节最大高度(格,Z 轴) | [Spacing 间距] VerticalThinMaxCells = 1.45(不要 ≥1.5) |
| 蓝图安全整数格模式 | [Spacing 间距] BlueprintSafe = true |
| 自动拉平(默认关,开了可能扭) | [Flatten 自动拉平] Enable = true |
改完保存即可;被 F9 开关的那个值会立刻反映在日志里(
间距已开启/关闭)。
6. 怎么确认模组真的生效(v1.0.1 之后的验证流程)
- 看 BepInEx 日志开头:应出现
[Info : BepInEx] Loading [Tropic Belt Spacing 1.5.5] [Info :Tropic Belt Spacing] 开关快捷键 / toggle hotkey = F9 (默认 F9;本模组没有游戏内 UI,全部设置都在 BepInEx\config\TropicBeltSpacing.cfg) [Info :Tropic Belt Spacing] 当前状态 / spacing = 开启(省料间距) - 看 BepInEx 日志(
BepInEx\LogOutput.log)应该出现三行补丁结果:
任何一行是[Info :Tropic Belt Spacing] 补丁成功 / patch OK: PlanetGrid.SnapLineNonAlloc (间距核心) [Info :Tropic Belt Spacing] 补丁成功 / patch OK: PlanetAuxData.SnapLineNonAlloc (兜底抽稀) [Info :Tropic Belt Spacing] 补丁成功 / patch OK: BuildTool_Path.DeterminePreviews (自动拉平)补丁失败 / patch FAILED就说明该补丁没挂上(把日志发我)。 - 拖一条传送带:日志里每秒最多一条
日志里[Info :Tropic Belt Spacing] [TropicBeltSpacing] lat=32.1° band=1 cells=1.618 target=2.033m nodes 238->31节点 238->31就是“同样长度、带子数量少了约 8 倍”。 - 如果日志里没有那三行:
- 先确认本模组自己有没有报错(
[Error :Tropic Belt Spacing])。本模组不依赖其它模组, 只要patch OK三行都在,拖传送带就应该看到nodes N->M变化。 - 如果同时装了别的会改传送带节点间距的模组(例如 LongerBelts 的「更改经纬线模式默认跨度」), 两者会同时作用在同一条带子上。本模组已经加了双向校正兜底: 对方生成得比目标密→会被抽稀;比目标**明显稀疏或超过 sqrt(5.3)**→会被拆短; 但如果对方输出的是 1.8 格这种"刚好比赤道带目标 1.6 格稀一点点"的间距, 数学上没法只靠删/插把每一节都变成 1.6 格(会造出更短的碎节),这时本模组会保持它的间距。 想要严格按回归线分带(赤道 1.6 格 → 极区 1.8 格),建议只保留本模组,把另一个关掉。
- 确认游戏版本与 mod 是否匹配(本模组基于 0.10.35 的
Assembly-CSharp.dll核对过签名)。
- 先确认本模组自己有没有报错(
7. 已知限制
- 只影响普通(经纬线)模式的传送带节点间距;按 R 切换的“测地线模式”保持原版行为。
- 抽稀只减少节点,不增加:一笔拖拽能覆盖的路径长度与原版一致(原版
BuildTool_Path.pathPoints是 256 个元素)。 - 竖直拉平只处理“整条路径都是传送带”的情况,避免影响其它建筑的建造判定。
- 本产物:已用本机游戏(0.10.35,
Assembly-CSharp.dll)反编译核对过补丁目标签名与关键机制, 并完成编译与算法数值验证,且已在游戏内实机验证(分带省料、斜坡/垂直抽稀、F9 开关)。
8. 目录结构
TropicBeltSpacing/
├─ src/
│ ├─ Plugin.cs BepInEx 插件入口(F9 开关、补丁挂载)
│ ├─ ModConfig.cs cfg 配置项
│ ├─ TropicBands.cs 回归线分带表与间距换算
│ ├─ BeltSpacingCore.cs 核心:间距/抽稀算法(PlanetGrid.SnapLineNonAlloc 前置补丁)
│ ├─ Flatten.cs 自动拉平(默认关闭)
│ ├─ Patches.cs Harmony 补丁声明
│ ├─ Hotkeys.cs F9 开关快捷键(无 UI)
│ └─ Compat.cs 接管 LongerBelts 类经纬线长带模组
├─ TropicBeltSpacing.csproj
├─ build.ps1
└─ dist/ 编译输出(BepInEx/plugins/... 结构)