作者:rebot | 分类:模组
Minecraft 版本: 1.21.1
平台: neoforge
标签: adventure game-mechanics technology
Sable: Destructive is a NeoForge 1.21.1 add-on for Sable that turns physics blocks into something that can actually be destroyed. Crash a ship into the ground, set off a creeper next to a flying base, or drop an end crystal on a tank — Sable sub-levels now react to violence the way they should: chunks fly off, weak materials pulverize, and reinforced ones hold.
Out of the box, Sable gives you beautifully simulated physics blocks, but they are effectively indestructible. This add-on plugs directly into Sable's collision and explosion callbacks and decides, on every meaningful impact, whether the affected blocks should:
The choice between the two is not a flat dice roll. It is biased by real physics:
You see the underlying numbers right in-game with F3 + H:
Mass: 540 kg
Impact strength: 20 m/s
NaN/Inf, mid-step mutation, and cross-parent cluster errors. Years of "Minecraft just closed without a log" — fixed.config/sabledestructive-common.toml. Every value set via /sable-dv set … survives restarts, and editing the TOML on disk hot-reloads within ~250 ms.0.5 · m · v_thr²). An obsidian hammer punches a deep crater into dirt and only chips the surface of stone, automatically.ServerSubLevel#getMassTracker() — the same number Rapier uses for the physics body. Pre-1.6.0 every attacker was hard-coded to 2 t for break purposes, so a 100 kg flying chunk and a 500 t fortress felt identical. Now a fortress crushes obsidian from inertia while a thrown cobble bounces off stone. The structural-toughness gate also gets a sqrt(refMass / realMass) relief factor, floored at 10×, so a 100 t crusher made of packed dirt pulverises stone but a Jell-O sub-level at any mass still can't peel bedrock.getDestroySpeed < 0 is rejected, attacker-vs-defender toughness ratio is enforced (a 20-unit attacker cannot break a 120-unit defender no matter how fast it goes — it erodes its own contact face instead), and a raw speed-vs-breakSpeedMs gate filters out trivial bumps. Bedrock inside a sub-level is now actually unbreakable.ceil(cbrt(targetSize)) around the seed, so clusters stay roughly spherical even on thin plating and a single-block contact can never spawn a line.Toughness: N units / Toughness: indestructible line uses translation keys and ships with English, Russian, German, Spanish, French, Portuguese (Brazil), Japanese, and Simplified Chinese.(v · n)² / |v|² — a sideways scrape on a wall deals a fraction of a head-on hit at the same speed, with a configurable floor so it never reaches zero./sable-dv mode delete — destruction only (VANISH, no new sub-levels spawn)./sable-dv mode detaching — default. Clean chunks peel off, nothing structural is silently deleted, world terrain is never touched, the shockwave only damages foliage./sable-dv mode delete-detaching — combo: seed peels off AND the inertial chain chews extra blocks deeper into the strike.All commands require op level 2.
/sable-dv on enable the system
/sable-dv off disable the system
/sable-dv toggle flip enabled
/sable-dv status current enabled state
/sable-dv mode show current collision mode
/sable-dv mode delete blocks only get destroyed
/sable-dv mode detaching default — clean chunks peel off
/sable-dv mode delete-detaching combo: seed detaches + chain breaks
/sable-dv config list list every tunable + current value
/sable-dv config get <name> read one value
/sable-dv config set <name> <value>
/sable-dv config reset <name>
Tunables include chanceDetach, chanceVanish, physicsBiasStrength, minBreakSpeed, absoluteMaxSpeed, detachSafeSpeedCeiling, maxDetachesPerSecond, maxActiveDetachedSubLevels, effects, fancyVanishEffect, affectOnlySubLevelBlocks, and many more.
Designed to stay quiet when nothing is happening, and not to fall over when everything is happening:
levelEvent(2001) if the fancy pipeline is overloaded.BlockToughness.Entry.UNBREAKABLE and the universal toughness gates make sure they survive even inside sub-levels).allowBlockEntityDetach=true and may corrupt mod-side network state.Sable: Destructive ships a small, stable, SemVer-covered public API so other mods can teach it about their blocks. Unknown modded blocks otherwise fall back to a deliberately fragile clay-tier default — register an entry and your block participates in real impact / explosion physics with the mass and toughness you choose.
The entire API lives in a single class: com.destroynautics.sabledestructive.api.SableDestructiveAPI. Anything outside that package is internal and may change between versions.
@Mod("examplemod")
public class ExampleMod {
public ExampleMod(IEventBus bus) {
bus.addListener(this::onCommonSetup);
}
private void onCommonSetup(FMLCommonSetupEvent e) {
// Direct Block reference (recommended, type-safe):
SableDestructiveAPI.register(
ExampleBlocks.MITHRIL_BLOCK.get(),
8500.0, // mass in kg
SableDestructiveAPI.Tier.NETHERITE);
// By ResourceLocation (works even if the target Block class isn't loaded —
// useful for optional cross-mod compat):
SableDestructiveAPI.register(
ResourceLocation.fromNamespaceAndPath("othermod", "arcane_brick"),
3000.0,
SableDestructiveAPI.Tier.STONE);
// Custom raw values (advanced):
SableDestructiveAPI.register(
ExampleBlocks.FOAM_PANEL.get(),
40.0, // very light (kg)
0.8); // very fragile (~8 toughness units)
// Bedrock-equivalent:
SableDestructiveAPI.registerUnbreakable(ExampleBlocks.WARDSTONE.get());
}
}
Use SableDestructiveAPI.Tier instead of magic numbers — your blocks then stay balanced relative to vanilla as the mod's defaults evolve.
| Tier | Toughness (units) | Vanilla example |
|---|---|---|
PAPER |
10 | flowers, candles |
LEAF |
15 | leaves, vines |
EARTH |
20 | dirt, sand, gravel |
CLOTH |
30 | wool, hay, cobwebs |
SOFT |
40 | sponge, slime, snow |
CLAY |
60 | clay, ice, terracotta |
WOOD |
120 | logs, planks |
STONE |
200 | stone, cobble |
HARD_STONE |
280 | deepslate |
METAL_SOFT |
340 | gold, copper |
METAL |
420 | iron, anvil |
GEM |
520 | diamond, emerald |
OBSIDIAN |
700 | obsidian |
NETHERITE |
1000 | netherite, ancient debris |
REINFORCED |
2000 | reinforced deepslate |
UNBREAKABLE |
∞ | bedrock, barrier |
// Register / override
SableDestructiveAPI.register(Block, double massKg, double breakSpeedMs)
SableDestructiveAPI.register(Block, double massKg, Tier tier)
SableDestructiveAPI.registerUnbreakable(Block)
// By ResourceLocation (optional cross-mod compat)
SableDestructiveAPI.register(ResourceLocation, double massKg, double breakSpeedMs)
SableDestructiveAPI.register(ResourceLocation, double massKg, Tier tier)
SableDestructiveAPI.registerUnbreakable(ResourceLocation)
// Inspect / remove
boolean SableDestructiveAPI.isRegistered(Block)
void SableDestructiveAPI.unregister(Block)
// Read-only queries (e.g. for your own tooltips / ballistics)
double SableDestructiveAPI.getMassKg(BlockState)
double SableDestructiveAPI.getBreakSpeedMs(BlockState)
double SableDestructiveAPI.getToughnessUnits(BlockState) // m/s × 10
Toughness: N units where N = breakSpeedMs × 10.Add Sable: Destructive as an optional runtime dependency in your neoforge.mods.toml so your mod loads either way:
[[dependencies.examplemod]]
modId = "sabledestructive"
type = "optional"
versionRange = "[1.1.0,)"
ordering = "AFTER"
side = "BOTH"
Then guard your registration call so it doesn't NoClassDefFoundError when Sable: Destructive isn't installed:
if (ModList.get().isLoaded("sabledestructive")) {
ExampleSableCompat.register(); // wraps the SableDestructiveAPI calls
}
请登录后举报
暂无评论,抢个沙发吧~