create-simulated-aeronautics-mod
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCreate Simulated Project (Aeronautics)
Create Simulated Project (Aeronautics)
What Is This Project?
该项目是什么?
The Simulated Project is a suite of NeoForge Minecraft mods that extend the Create mod with real-time physics-based contraptions. It consists of three interconnected mods:
| Mod | Purpose |
|---|---|
| Create Simulated | Core assembly system, redstone components, physics interaction API |
| Create Aeronautics | Flying contraptions — propellers, hot air, levitation rocks |
| Create Offroad | Land vehicles — wheels, suspension, terrain traversal |
Physics simulation is powered by Sable, a custom rigid-body physics engine built for Minecraft contraptions.
Installation (Player/Server)
安装(玩家/服务器)
Modrinth (Recommended)
Modrinth(推荐)
- Download from modrinth.com/project/create-aeronautics
- Place the JAR(s) in your folder alongside dependencies
mods/
- 从modrinth.com/project/create-aeronautics下载
- 将JAR文件放入你的文件夹中,并确保依赖模组已安装
mods/
Required Dependencies
必需依赖
- NeoForge (matching the mod's target Minecraft version)
- Create mod (matching version)
- Sable physics library
- NeoForge(需与模组目标Minecraft版本匹配)
- Create模组(版本匹配)
- Sable物理库
Recommended Launcher
推荐启动器
Use Modrinth App or Prism Launcher for dependency resolution.
使用Modrinth App或Prism Launcher来自动处理依赖。
Developer Setup (Building from Source)
开发者设置(从源码构建)
Clone & Build
克隆与构建
bash
git clone https://github.com/Creators-of-Aeronautics/Simulated-Project.git
cd Simulated-Project
./gradlew buildbash
git clone https://github.com/Creators-of-Aeronautics/Simulated-Project.git
cd Simulated-Project
./gradlew buildRun in Dev Environment
在开发环境中运行
bash
undefinedbash
undefinedStart a development client
Start a development client
./gradlew runClient
./gradlew runClient
Start a development server
Start a development server
./gradlew runServer
./gradlew runServer
Generate IDE run configurations (IntelliJ)
Generate IDE run configurations (IntelliJ)
./gradlew genIntellijRuns
undefined./gradlew genIntellijRuns
undefinedProject Structure
项目结构
Simulated-Project/
├── simulated/ # Core mod — assembly, physics API
├── aeronautics/ # Flying contraptions submod
├── offroad/ # Land vehicle submod
├── common/ # Shared utilities across submods
└── build.gradle # Multi-project Gradle buildSimulated-Project/
├── simulated/ # Core mod — assembly, physics API
├── aeronautics/ # Flying contraptions submod
├── offroad/ # Land vehicle submod
├── common/ # Shared utilities across submods
└── build.gradle # Multi-project Gradle buildCore Concepts
核心概念
1. Simulated Contraptions
1. 模拟装置
Unlike vanilla Create contraptions (which move block-by-block along tracks), Simulated contraptions are assembled into physics objects with:
- Mass derived from block composition
- Moment of inertia for rotation
- Forces applied by thrusters, propellers, wheels
与原版Create装置(沿轨道逐块移动)不同,Simulated装置被组装成具有以下特性的物理对象:
- 质量:由组成方块的材质决定
- 转动惯量:影响旋转特性
- 受力:由推进器、螺旋桨、车轮施加
2. Assembly
2. 装配
Players assemble a contraption using a designated assembly block (similar to Create's mechanical bearing). Once assembled, the structure becomes a rigid physics body managed by Sable.
玩家使用指定的装配方块(类似Create的机械轴承)来组装装置。装配完成后,该结构将成为由Sable管理的刚体物理实体。
3. Force Providers
3. 力提供者
Blocks that apply forces to assembled contraptions:
- — directional thrust (Aeronautics)
PropellerBlock - — upward buoyancy (Aeronautics)
HotAirBlock - — magical lift (Aeronautics)
LevitationRockBlock - — ground traction and propulsion (Offroad)
WheelBlock
为已装配装置施加力的方块:
- — 定向推力(Aeronautics)
PropellerBlock - — 向上浮力(Aeronautics)
HotAirBlock - — 魔法升力(Aeronautics)
LevitationRockBlock - — 地面牵引力与推进力(Offroad)
WheelBlock
Key API — Create Simulated Core
核心API — Create Simulated Core
Registering a Custom Force Provider
注册自定义力提供者
java
import com.simulated.api.force.IForceProvider;
import com.simulated.api.contraption.SimulatedContraption;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import org.joml.Vector3f;
public class MyThrusterBlock extends Block implements IForceProvider {
public MyThrusterBlock(Properties properties) {
super(properties);
}
@Override
public Vector3f getForce(SimulatedContraption contraption, BlockPos localPos, Level level) {
// Return force vector in world space (Newtons equivalent)
// Positive Y = upward lift, positive Z = forward thrust
float thrustMagnitude = 500.0f;
return new Vector3f(0, 0, thrustMagnitude);
}
@Override
public Vector3f getTorque(SimulatedContraption contraption, BlockPos localPos, Level level) {
// Torque applied around center of mass (optional)
return new Vector3f(0, 0, 0);
}
}java
import com.simulated.api.force.IForceProvider;
import com.simulated.api.contraption.SimulatedContraption;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import org.joml.Vector3f;
public class MyThrusterBlock extends Block implements IForceProvider {
public MyThrusterBlock(Properties properties) {
super(properties);
}
@Override
public Vector3f getForce(SimulatedContraption contraption, BlockPos localPos, Level level) {
// Return force vector in world space (Newtons equivalent)
// Positive Y = upward lift, positive Z = forward thrust
float thrustMagnitude = 500.0f;
return new Vector3f(0, 0, thrustMagnitude);
}
@Override
public Vector3f getTorque(SimulatedContraption contraption, BlockPos localPos, Level level) {
// Torque applied around center of mass (optional)
return new Vector3f(0, 0, 0);
}
}Registering Your Block with NeoForge
向NeoForge注册方块
java
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.level.block.Block;
import net.neoforged.neoforge.registries.DeferredHolder;
public class MyModBlocks {
public static final DeferredRegister<Block> BLOCKS =
DeferredRegister.create(BuiltInRegistries.BLOCK, "mymod");
public static final DeferredHolder<Block, MyThrusterBlock> MY_THRUSTER =
BLOCKS.register("my_thruster", () -> new MyThrusterBlock(
Block.Properties.of().strength(2.0f)
));
public static void register(IEventBus eventBus) {
BLOCKS.register(eventBus);
}
}java
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.level.block.Block;
import net.neoforged.neoforge.registries.DeferredHolder;
public class MyModBlocks {
public static final DeferredRegister<Block> BLOCKS =
DeferredRegister.create(BuiltInRegistries.BLOCK, "mymod");
public static final DeferredHolder<Block, MyThrusterBlock> MY_THRUSTER =
BLOCKS.register("my_thruster", () -> new MyThrusterBlock(
Block.Properties.of().strength(2.0f)
));
public static void register(IEventBus eventBus) {
BLOCKS.register(eventBus);
}
}Accessing a SimulatedContraption at Runtime
在运行时访问SimulatedContraption
java
import com.simulated.api.contraption.SimulatedContraption;
import com.simulated.api.contraption.SimulatedContraptionHandler;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
public class ContraptionUtils {
/**
* Get the simulated contraption an entity is riding, if any.
*/
public static SimulatedContraption getRiddenContraption(Entity entity) {
return SimulatedContraptionHandler.getContraptionForEntity(entity);
}
/**
* Apply an impulse to a contraption's physics body directly.
*/
public static void applyImpulse(SimulatedContraption contraption, Vec3 impulse) {
contraption.getPhysicsBody().applyImpulse(
new org.joml.Vector3f(
(float) impulse.x,
(float) impulse.y,
(float) impulse.z
)
);
}
}java
import com.simulated.api.contraption.SimulatedContraption;
import com.simulated.api.contraption.SimulatedContraptionHandler;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
public class ContraptionUtils {
/**
* Get the simulated contraption an entity is riding, if any.
*/
public static SimulatedContraption getRiddenContraption(Entity entity) {
return SimulatedContraptionHandler.getContraptionForEntity(entity);
}
/**
* Apply an impulse to a contraption's physics body directly.
*/
public static void applyImpulse(SimulatedContraption contraption, Vec3 impulse) {
contraption.getPhysicsBody().applyImpulse(
new org.joml.Vector3f(
(float) impulse.x,
(float) impulse.y,
(float) impulse.z
)
);
}
}Listening to Contraption Assembly Events
监听装置装配事件
java
import com.simulated.api.event.ContraptionAssembleEvent;
import com.simulated.api.event.ContraptionDisassembleEvent;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
@EventBusSubscriber(modid = "mymod")
public class ContraptionEventHandler {
@SubscribeEvent
public static void onAssemble(ContraptionAssembleEvent event) {
SimulatedContraption contraption = event.getContraption();
// e.g., calculate custom mass modifier
float customMass = contraption.getMass() * 0.8f;
contraption.setMassOverride(customMass);
System.out.println("Contraption assembled with " +
contraption.getBlocks().size() + " blocks.");
}
@SubscribeEvent
public static void onDisassemble(ContraptionDisassembleEvent event) {
// Cleanup any custom data attached to this contraption
MyContraptionData.remove(event.getContraption().getId());
}
}java
import com.simulated.api.event.ContraptionAssembleEvent;
import com.simulated.api.event.ContraptionDisassembleEvent;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
@EventBusSubscriber(modid = "mymod")
public class ContraptionEventHandler {
@SubscribeEvent
public static void onAssemble(ContraptionAssembleEvent event) {
SimulatedContraption contraption = event.getContraption();
// e.g., calculate custom mass modifier
float customMass = contraption.getMass() * 0.8f;
contraption.setMassOverride(customMass);
System.out.println("Contraption assembled with " +
contraption.getBlocks().size() + " blocks.");
}
@SubscribeEvent
public static void onDisassemble(ContraptionDisassembleEvent event) {
// Cleanup any custom data attached to this contraption
MyContraptionData.remove(event.getContraption().getId());
}
}Aeronautics — Flight Mechanics
Aeronautics — 飞行机制
Propeller Configuration (In-Game)
螺旋桨配置(游戏内)
Propellers are directional. Place them facing the direction you want thrust:
- Facing down → upward lift
- Facing back → forward thrust
- Speed (RPM) fed by Create's rotational network controls thrust magnitude
螺旋桨具有方向性,将其朝向你需要推力的方向放置:
- 朝下 → 向上升力
- 朝后 → 向前推力
- 由Create旋转网络提供的转速(RPM)控制推力大小
Hot Air Balloon
热气球
- Place Balloon Canvas blocks in a dome shape above a heat source
- Connect a Blaze Burner below the opening
- Assemble — the trapped hot air provides buoyancy proportional to enclosed volume
- 在热源上方放置Balloon Canvas方块形成圆顶形状
- 在开口下方连接Blaze Burner
- 装配——封闭的热空气会根据体积提供相应的浮力
Levitation Rock
浮空石
- Rare ore providing passive vertical lift
- Useful for lighter-than-air vessels needing no fuel
- 提供被动垂直升力的稀有矿石
- 适用于无需燃料的轻于空气的载具
Flight Control Pattern
飞行控制示例
java
// Example: Redstone-controlled pitch adjustment via a custom block entity
public class FlightControllerBlockEntity extends BlockEntity {
public FlightControllerBlockEntity(BlockPos pos, BlockState state) {
super(MyModBlockEntities.FLIGHT_CONTROLLER.get(), pos, state);
}
public void applyPitchInput(SimulatedContraption contraption, float pitchDelta) {
// Torque around the X-axis to pitch the vehicle
org.joml.Vector3f torque = new org.joml.Vector3f(pitchDelta * 100f, 0, 0);
contraption.getPhysicsBody().applyTorqueImpulse(torque);
}
}java
// Example: Redstone-controlled pitch adjustment via a custom block entity
public class FlightControllerBlockEntity extends BlockEntity {
public FlightControllerBlockEntity(BlockPos pos, BlockState state) {
super(MyModBlockEntities.FLIGHT_CONTROLLER.get(), pos, state);
}
public void applyPitchInput(SimulatedContraption contraption, float pitchDelta) {
// Torque around the X-axis to pitch the vehicle
org.joml.Vector3f torque = new org.joml.Vector3f(pitchDelta * 100f, 0, 0);
contraption.getPhysicsBody().applyTorqueImpulse(torque);
}
}Offroad — Land Vehicles
Offroad — 陆地载具
Wheel Setup
车轮设置
- Place Wheel blocks at the four corners of your vehicle chassis
- Each wheel needs rotational input from Create's shaft network
- Assemble the contraption — wheels automatically detect ground contact
- 在载具底盘的四个角放置Wheel blocks
- 每个车轮需要来自Create轴网络的旋转输入
- 装配装置——车轮会自动检测地面接触
Suspension
悬挂系统
Wheels simulate suspension travel. Stiffer suspensions use more rigid Create structural blocks near the wheel mounts.
车轮模拟悬挂行程。在车轮安装座附近使用更坚固的Create结构方块可获得更硬的悬挂。
Steering
转向
Connect Create's Rotation Speed Controller to front wheels to implement steering differentials.
将Create的Rotation Speed Controller连接到前轮,以实现转向差速器。
Configuration
配置
Config files generate in on first run:
config/toml
undefined首次运行时,配置文件会生成在目录中:
config/toml
undefinedsimulated-common.toml
simulated-common.toml
[physics]
Physics simulation tick rate (ticks per second, default 20)
simulationRate = 20
Maximum contraption block count before performance warnings
maxContraptionSize = 2048
Enable contraption–contraption collision
contraptionCollision = true
[aeronautics]
Propeller force multiplier
propellerForceScale = 1.0
Hot air buoyancy multiplier
hotAirBuoyancyScale = 1.0
[offroad]
Wheel traction coefficient
wheelTraction = 0.85
Maximum vehicle speed (blocks/second)
maxVehicleSpeed = 40.0
---[physics]
Physics simulation tick rate (ticks per second, default 20)
simulationRate = 20
Maximum contraption block count before performance warnings
maxContraptionSize = 2048
Enable contraption–contraption collision
contraptionCollision = true
[aeronautics]
Propeller force multiplier
propellerForceScale = 1.0
Hot air buoyancy multiplier
hotAirBuoyancyScale = 1.0
[offroad]
Wheel traction coefficient
wheelTraction = 0.85
Maximum vehicle speed (blocks/second)
maxVehicleSpeed = 40.0
---Localization / Translations
本地化/翻译
Adding a New Language
添加新语言
- Join the Crowdin project
- Translate strings in the web UI
- Translations are automatically pulled into the repo
- 加入Crowdin项目
- 在网页界面中翻译字符串
- 翻译内容会自动同步到代码仓库
Adding Keys Programmatically
通过代码添加翻译键
java
// In your lang JSON: src/main/resources/assets/mymod/lang/en_us.json
{
"block.mymod.my_thruster": "Hyperdrive Thruster",
"block.mymod.my_thruster.tooltip": "Applies directional thrust to assembled contraptions.",
"mymod.contraption.overloaded": "Contraption mass exceeds safe limits!"
}java
// In your lang JSON: src/main/resources/assets/mymod/lang/en_us.json
{
"block.mymod.my_thruster": "Hyperdrive Thruster",
"block.mymod.my_thruster.tooltip": "Applies directional thrust to assembled contraptions.",
"mymod.contraption.overloaded": "Contraption mass exceeds safe limits!"
}Common Patterns
常见模式
Pattern 1: Fuel-Gated Thrust
模式1:燃料驱动推力
java
@Override
public Vector3f getForce(SimulatedContraption contraption, BlockPos localPos, Level level) {
// Only provide thrust if a fuel item is present in an adjacent chest
BlockEntity adjacent = level.getBlockEntity(localPos.above());
if (adjacent instanceof net.minecraft.world.level.block.entity.ChestBlockEntity chest) {
boolean hasFuel = !chest.isEmpty(); // simplified check
if (hasFuel) {
return new Vector3f(0, 0, 800.0f);
}
}
return new Vector3f(0, 0, 0);
}java
@Override
public Vector3f getForce(SimulatedContraption contraption, BlockPos localPos, Level level) {
// Only provide thrust if a fuel item is present in an adjacent chest
BlockEntity adjacent = level.getBlockEntity(localPos.above());
if (adjacent instanceof net.minecraft.world.level.block.entity.ChestBlockEntity chest) {
boolean hasFuel = !chest.isEmpty(); // simplified check
if (hasFuel) {
return new Vector3f(0, 0, 800.0f);
}
}
return new Vector3f(0, 0, 0);
}Pattern 2: Speed-Based Thrust Scaling
模式2:基于速度的推力缩放
java
@Override
public Vector3f getForce(SimulatedContraption contraption, BlockPos localPos, Level level) {
// Scale thrust with Create rotational speed at this block's position
float rpm = contraption.getRotationalSpeedAt(localPos);
float thrust = rpm * 2.5f; // tune this constant for your use case
return new Vector3f(0, 0, Math.min(thrust, 2000.0f)); // cap at max
}java
@Override
public Vector3f getForce(SimulatedContraption contraption, BlockPos localPos, Level level) {
// Scale thrust with Create rotational speed at this block's position
float rpm = contraption.getRotationalSpeedAt(localPos);
float thrust = rpm * 2.5f; // tune this constant for your use case
return new Vector3f(0, 0, Math.min(thrust, 2000.0f)); // cap at max
}Pattern 3: Custom Physics Data per Contraption
模式3:每个装置的自定义物理数据
java
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class MyContraptionData {
private static final Map<UUID, Float> fuelLevels = new HashMap<>();
public static float getFuel(UUID contraptionId) {
return fuelLevels.getOrDefault(contraptionId, 100.0f);
}
public static void consumeFuel(UUID contraptionId, float amount) {
float current = getFuel(contraptionId);
fuelLevels.put(contraptionId, Math.max(0, current - amount));
}
public static void remove(UUID contraptionId) {
fuelLevels.remove(contraptionId);
}
}java
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class MyContraptionData {
private static final Map<UUID, Float> fuelLevels = new HashMap<>();
public static float getFuel(UUID contraptionId) {
return fuelLevels.getOrDefault(contraptionId, 100.0f);
}
public static void consumeFuel(UUID contraptionId, float amount) {
float current = getFuel(contraptionId);
fuelLevels.put(contraptionId, Math.max(0, current - amount));
}
public static void remove(UUID contraptionId) {
fuelLevels.remove(contraptionId);
}
}Troubleshooting
故障排除
| Symptom | Likely Cause | Fix |
|---|---|---|
| Contraption won't assemble | Missing dependency mod (Create, Sable) | Verify all deps in |
| Vehicle sinks through floor | Wheel blocks not receiving rotation | Check shaft connections |
| Extreme jitter / vibration | Too many conflicting force providers | Balance thrust/lift forces; reduce |
| Crash on assembly | Block count exceeds | Increase limit in config or reduce vehicle size |
| Translations not showing | Wrong lang file path | Ensure |
| Physics desync on multiplayer | High server TPS drop | Lower |
| API jar not in classpath | Add |
| 症状 | 可能原因 | 解决方法 |
|---|---|---|
| 装置无法装配 | 缺少依赖模组(Create、Sable) | 确认 |
| 载具沉入地面 | 车轮方块未接收到旋转输入 | 检查轴连接 |
| 极端抖动/震动 | 存在过多相互冲突的力提供者 | 平衡推力/升力;在配置中降低 |
| 装配时崩溃 | 方块数量超过 | 在配置中提高限制或减小载具尺寸 |
| 翻译未显示 | 语言文件路径错误 | 确保 |
| 多人游戏中物理不同步 | 服务器TPS大幅下降 | 降低 |
IForceProvider出现 | API jar不在类路径中 | 将 |
Dependency Setup in build.gradle
build.gradlebuild.gradle
中的依赖设置
build.gradlegroovy
dependencies {
// NeoForge
implementation "net.neoforged:neoforge:${neoforge_version}"
// Create mod (via cursemaven or modrinth maven)
implementation fg.deobf("com.simibubi.create:create-${minecraft_version}:${create_version}:slim") {
transitive = false
}
// Create Simulated API (once published to maven)
implementation "com.aeronautics:simulated-api:${simulated_version}"
}groovy
dependencies {
// NeoForge
implementation "net.neoforged:neoforge:${neoforge_version}"
// Create mod (via cursemaven or modrinth maven)
implementation fg.deobf("com.simibubi.create:create-${minecraft_version}:${create_version}:slim") {
transitive = false
}
// Create Simulated API (once published to maven)
implementation "com.aeronautics:simulated-api:${simulated_version}"
}Community & Support
社区与支持
- Discord: discord.gg/createaeronautics
- Issue Tracker: GitHub Issues (233 open)
- Modrinth: modrinth.com/project/create-aeronautics
- Crowdin Translations: crowdin.com/project/create-aeronautics
- Discord: discord.gg/createaeronautics
- 问题追踪: GitHub Issues(233个未解决)
- Modrinth: modrinth.com/project/create-aeronautics
- Crowdin翻译: crowdin.com/project/create-aeronautics