This guide is intended for Java (and sometimes JSON) mods. If you are using JS, please don't - I very rarely use JS myself, and I can't give accurate instructions for porting.
Before you do anything, read the old v7 porting guide and make sure you have no deprecation warnings in your mod, because everything that was deprecated then has since been removed. I will not be covering deprecated API here.
Replace your Mindustry dependencies in build.gradle
with the following:
compileOnly "com.github.Anuken.MindustryJitpack:core:9872c62de6"
compileOnly "com.github.Anuken.Arc:arc-core:89f5cbe7ab"
Note that the jitpack repository is now MindustryJitpack, not Mindustry. Why? Because JITPack sucks, but that's a story for another time.
For the absolute latest versions of Mindustry/Arc, replace the commit hashes at the ends with the latest commit hash of the corresponding repository.
- Weapons and turrets now have a
ShootPattern shoot
field. - This pattern controls how, where and when bullets are created.
- Fields like
shots
,chargeTime
andspread
have been moved into this object. - The default ShootPattern implementation has no spread, and only supports a
firstShotDelay
(charging) andshotDelay
(delay between shots)
Patterns of interest:
ShootSpread
: Shotgun of projectiles with configurable spread.ShootAlternate
: Duo/spectre double barrel shots.ShootBarrel
: Similar to ShootAlternate, but barrels can be at any position or rotation.ShootMulti
: Chain together patterns, so you can have something like a duo that shoots a shotgun out of each barrel.
Many DrawBlock subclasses have been removed, as they are now redundant. Block drawers are now modular, which means you can compose different layers instead of using one specific DrawBlock type.
As an example, here is how a cryofluid mixer's drawer is implemented:
drawer = new DrawMulti(new DrawRegion("-bottom"), new DrawLiquidTile(Liquids.cryofluid), new DrawDefault());
- DrawMulti simply combines multiple draw implementations.
- DrawRegion draws a region named
cryofluid-mixer-bottom
as the first layer. - DrawLiquidTile draws an animated square region of cryofluid liquid, with opacity depending on how full the block is.
- DrawDefault draws the default block sprites (in this case, the top with its glass cover)
For a variety of examples on how to use DrawBlocks, consult the source code.
Most fields have been renamed to match weapons.
reloadTime -> reload
shootLength -> shootY
recoilAmount -> recoil
shootShake -> shake
chargeEffect/chargeBeginEffect -> moved into bullet
cooldown, restitution -> no direct equivalent, either remove or use cooldownTime and recoilTime instead (see javadoc)
#THIS IS VERY IMPORTANT AND CAN LEAD TO BIZZARRE BUGS IF YOU DO NOT HANDLE IT PROPERLY
reload (TurretBuild) -> reloadCounter
recoil (TurretBuild) -> curRecoil
consumes
is gone.efficiency
has been changed to reflect a block's "real" efficiency, not just power.- If a block's
shouldConsume
returns false or it has no items, this efficiency is now 0, even if it has power. - If you want to get the efficiency a block would have had if shouldConsume was true, use
potentialEfficiency
. - This has been implemented to better support fluid networks or partial consumption in the future. For example, a block getting 1 liquid a frame when it needs 10 liquid a frame will have 10% efficiency every frame, instead of having consValid() return true every 10 frames.
- I'm still not sure about this system, let me know if it's horrible.
Names:
consValid() -> canConsume()
consumes.power -> consumePower
consumes.item -> consumeItem
consumes.items -> consumeItems
consumes.liquid -> consumeLiquid
consumes.getPower() -> consPower
consumes.add -> consume
consumes.get(...) -> findConsumer(c -> c instanceof TheConsumeTypeYouWant) (and cache the result in init())
consumes.powerCond -> override shouldConsume instead, this is usually unnecessary
consumes.hasPower() -> consPower != null
cons.optionalValid() -> use optionalEfficiency, returns 0-1 like efficiency does
efficiency() -> efficiency (remove the method call, it's just a getter)
SingleTypeGenerator, ItemLiquidGenerator, BurnerGenerator, DecayGenerator -> ConsumeGenerator (see source for usage examples)
Block#canPlaceOn(Tile tile, Team team) -> Block#canPlaceOn(Tile tile, Team team, int rotation)
Vars.enableConsole -> removed, now a game setting
legTrns -> legForwardScl
visualElevation -> shadowElevation
rotateShooting -> faceTarget
mechStepShake -> stepShake
landShake -> mechLandShake
BulletType#range() -> BulletType#range
Vars.control.input.config.frag -> Vars.control.input.config
getSelectedTile() -> getSelected()
drawRequestRegion -> drawPlanRegion
drawRequestConfig -> drawPlanConfig
<any "build request method" now has "plan" in it>
onConfigureTileTapped -> onConfigureBuildTapped
PayloadAcceptor -> PayloadBlock
PayloadAcceptorBuild -> PayloadBlockBuild
#in setBars, you can find and replace this
bars.add(" -> addBar("
bars.remove(" -> removeBar("
liquids.total() -> liquids.currentAmount()
expanded -> in init(), call `updateClipRadius(<the maximum draw radius of your block>)`
ContentList -> remove the interface, make the load() method static and call YourClass.load()
Fragment -> remove the interface and just call load()
scaleVelocity -> scaleLife
fragCone -> fragRandomSpread
#team parameter has been removed
Drawf.light(team, -> Drawf.light(
Drawf.laser(team, -> Drawf.laser(
BulletType#range() -> BulletType#calculateRange()
Styles.transt -> Styles.cleart
Styles.clearTransi -> Styles.cleari
Styles.accenti -> Styles.grayi
Styles.clearPartialt -> Styles.flatBordert
Styles.clearPartiali -> Styles.clearNonei
Styles.clearTogglet -> Styles.flatTogglet
Styles.clearToggleTransi -> Styles.clearTogglei
Styles.clearTogglePartiali -> Styles.clearNoneTogglei
Styles.colori -> removed, it was just an ImageButtonStyle with an imageUpColor being Color.white
Lines.polySeg -> Lines.arc (different parameter order!)
Lines.swirl -> Lines.arc
Structs.select -> Structs.random
If you've used an IDE much before, you should know about this, but just to be clear: Don't even think of doing most of these changes manually. For simple things like consumes.power
-> consumePower
, you should be opening InteliiJ's global replace dialog (ctrl-shift-r) and replacing it across your entire codebase. If you have a JSON mod, you can still open your mod folder in something like VS Code and replace (ctrl-shift-h) every occurence of, say, reloadTime
with reload
.
Is there a guide on how to use new TechTree API. I can't figure out how to add new nodes to existing (vanilla) tree.