Sable: Destructive
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.
What it does
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:
- DETACH — break off into a smaller, independent physics sub-level. The piece keeps flying, tumbling, and colliding on its own.
- VANISH — pulverize into particles + sound, with a multi-layer shatter effect. Used when the energy is high enough to truly shatter the material.
The choice between the two is not a flat dice roll. It is biased by real physics:
- Kinetic energy at the contact point (mass × v²) vs. material toughness.
- Block brittleness (leaves and grass shatter; obsidian and netherite resist).
- A safety speed ceiling so absurdly fast impacts don't spawn endless sub-levels.
You see the underlying numbers right in-game with F3 + H:
Toughness: 20 units
(Mass / impact strength diagnostics also appear where available.)
Features
- ✅ Full impact handling for all 1.21.1 blocks, with a sensible mass + toughness table.
- ✅ Modded blocks default to the fragile end (clay-tier) so unknown blocks don't become indestructible bricks.
- ✅ Vanilla explosions are routed through the same path: TNT, creepers, end crystals, beds-in-the-Nether all damage Sable sub-levels.
- ✅ World terrain is also affected, but only via VANISH (never DETACH), so the world never turns into a runaway physics sim. There's a config flag to restrict damage to sub-level blocks only.
- ✅ Fancy VANISH effect: multi-layer particles (block-dust with the actual block texture, grit, shockwave dust) + break sound + soft thud, with hard per-tick budgets so mass breaks don't tank your FPS.
- ✅ Sub-level FX (2.0.0): dust and grit ride the ship — packets carry plot-local coords and the client embeds particles into the live sub-level pose.
- ✅ Crash-safe: every native call into Sable is wrapped, deferred to safe inter-tick windows, and guarded against
NaN/Inf, mid-step mutation, cross-parent cluster errors, and assemble-into-removed-plot races. - ✅ Cluster detach: blocks can break off in chunks, not strictly one at a time, for cinematic damage.
- ✅ In-game config panel (2.0.0):
/sable-dv config panelopens a GUI — no restart required for most tunables. - ✅ Persistent config at
config/sabledestructive-common.toml. Values survive restarts; disk edits hot-reload. - ✅ Hand-tuned block table: ~70 of the most relevant 1.21.1 blocks — every wood species and the full stone family — carry their own mass and toughness instead of being lumped into one "wood" or "stone" bucket. Cherry is softer than oak. Mossy bricks crack a hair sooner than fresh ones. Slabs/stairs/walls/fences/doors/trapdoors/signs each get their own row. Other vanilla blocks continue to use the existing classification pipeline.
- ✅ Inertial penetration: impacts no longer stop at the first block. The attacker's kinetic energy is drained block-by-block along the motion direction by each consumed block's break cost (
0.5 · m · v_thr²). An obsidian hammer punches a deep crater into dirt and only chips the surface of stone, automatically. - ✅ Real damage: speed scales penetration depth and energy budget, and density actually matters — soft attackers no longer pretend to break hard surfaces.
- ✅ Self-damage: when the attacker is much softer than the defender, the defender survives AND the attacker erodes its own contact face. Copper hammer vs obsidian wall: copper sheds, wall stands.
- ✅ Real sub-level mass: the break decision and shockwave magnitude read each sub-level's actual mass (kg) straight from Sable's own mass tracker — the same number Rapier uses for the physics body. A fortress crushes 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. - ✅ Shockwave: only fires for genuinely substantial contacts. Magnitude is driven by real sub-level mass × an average-toughness constant. Radial dust burst plus a tall, slowly-rising semi-transparent dust column (mushroom shape, settles over a few seconds) plus one heavy thud, with per-source dedup and a per-tick particle budget. Radius and toughness ceiling both scale with the cube root of magnitude — small waves rip leaves, giant waves carve a real crater.
- ✅ Universal toughness gates: infinite toughness (bedrock, barrier, command block, end portal frame, structure block) is rejected, vanilla
getDestroySpeed < 0is rejected, attacker-vs-defender toughness ratio is enforced (a soft attacker cannot break a hard defender no matter how fast it goes — it erodes its own contact face instead), and a raw speed-vs-breakSpeedMsgate filters out trivial bumps. Bedrock inside a sub-level is actually unbreakable. - ✅ Spherical cluster detach: the cluster planner uses a distance-ordered priority queue and a hard Chebyshev radius cap of
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. - ✅ Localized tooltip (F3+H):
Toughness: N units/Toughness: indestructibleships with English, Russian, German, Spanish, French, Portuguese (Brazil), Italian, Polish, Japanese, Korean, Simplified Chinese, and Traditional Chinese. - ✅ Dot-product incidence: glancing blows actually glance. Damage scales with
(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. - ✅ Detach / vanish balance: tunables in the config panel and TOML control how often chunks peel off vs pulverize, energy bias, speed ceilings, and whether world terrain is touched at all.
Commands
All commands require op level 2.
/sable-dv on enable the system
/sable-dv off disable the system
/sable-dv config panel open the in-game config GUI (player only)
/sable-dv config reset reset all tunables to 2.0.0 defaults
/sable config panel alias — same config GUI
Tunables (detach chances, physics bias, speed ceilings, shockwave, FX budgets, affectOnlySubLevelBlocks, and many more) are edited in the config panel or in config/sabledestructive-common.toml.
Performance
Designed to stay quiet when nothing is happening, and not to fall over when everything is happening:
- Lock-free offer queue with atomic size counter and epoch-XOR dedup ring.
- Per-tick caps on offers, vanish particles, and vanish effects.
- Spatial + temporal dedup on effects so big breaks don't audio-clip.
- Auto-scaling under backpressure; falls back to vanilla
levelEvent(2001)if the fancy pipeline is overloaded. - DETACH is always deferred to a safe tick boundary — never executed while Sable's physics system is mid-step.
Requirements
- Minecraft 1.21.1
- NeoForge 21.1.235+
- Sable 2.0.3+ (required dependency — the add-on does literally nothing without it)
- Sable Companion + Veil (as required by your Sable install)
Compatibility
- Server + client. Effects are client-side; the destruction logic itself runs server-side.
- Should be compatible with most other mods. Modded blocks are auto-classified into a safe fragile tier.
- Create Aeronautics / Offroad / Simulated stacks that depend on Sable 2.x are supported at the dependency level; report crashes with the full log if a race still appears.
Known limitations
- Bedrock, barriers, and unbreakable blocks are skipped (by design —
BlockToughness.Entry.UNBREAKABLEand the universal toughness gates make sure they survive even inside sub-levels). - Block entities (chests, furnaces, Create cogwheels, etc.) prefer the VANISH path — peeling them into a new sub-level can corrupt mod-side network state if forced.
- Detach respects Sable's parent boundaries — clusters never cross sub-levels.
- Detach into an already-removed parent is refused; leftover pieces vanish instead of crashing Sable's heat-map assembler.
Credits
- Author / code: Xylos_Official
- Visuals: Viaquelt
- Built on top of: Sable by ryanhcode
