Physics-driven destruction for Sable: block-by-block impacts, craters, debris, dust plumes, shockwaves, camera shake, custom shaders and live server controls.
Автор: Xylos_Official16,9 тыс.48обновлён 24 июл. 2026 г.
Sable: Destructive is a server-and-client addon for Sable on Minecraft 1.21.1. It makes moving Sable structures respond to collisions and explosions with material-aware block failure, flying physics fragments, world craters, debris and cinematic impact effects.
Build a vehicle, aircraft, ship or moving base and crash it into the world. Weak contact blocks crush first, hard materials resist longer, detached pieces preserve their motion, and a sufficiently large body can create a radial crater with a visible pressure wave and rising column of dust.
Physical block damage
Every meaningful contact is evaluated using relative speed, reduced contact mass, kinetic energy, block mass, material toughness and the hardness of the attacking surface.
Block-by-block damage by default: ordinary collisions remove the actual contact block instead of carving long layers through the world.
Material compatibility: soft grass, leaves or dirt cannot destroy obsidian simply because more soft blocks are attached behind them.
Capped mass leverage: large structures hit harder, but mass cannot provide infinite strength to a weak contact face.
Attacker self-damage: when a soft projectile hits a hard wall, the projectile can erode while the wall survives.
Low-speed protection: a single stone block dropped from approximately two blocks will bounce or stop instead of drilling downward indefinitely.
Finite ordinary materials: stone, metals, obsidian, netherite and reinforced blocks are resistant, not immortal. A proportionate high-energy collision can still break them.
Optional penetration and cluster detachment can be enabled for more destructive servers. Penetration is energy-limited, requires extreme speed and is capped to prevent tunnelling.
Two destruction outcomes
When a block fails, Sable: Destructive chooses a result appropriate to the material and impact:
VANISH: brittle or heavily overloaded blocks pulverize into textured dust, grit and fragments without filling the world with dropped block items.
DETACH: suitable blocks peel away as independent Sable physics bodies that keep their inertia, tumble and collide with the environment.
Container contents can still be released, while unsafe block-entity detachment paths use the safer destruction outcome.
Giant landings
Large falling Sable bodies produce a multi-stage impact only after the system confirms real terrain contact:
A bright contact flash marks the instant of collision.
A dusty shock ring and a faster translucent pressure front expand across the ground.
Physical rock and soil fragments launch upward, fall under gravity and bounce off terrain.
A turbulent dust column rises above the crater and expands as it loses opacity.
Delayed skirt dust and secondary rubble settle around the impact site.
Layered boom, ground rumble and cracking sounds communicate the scale of the hit.
Distance-scaled camera and FOV vibration deliver a sharp kick followed by a slower tremor.
Crater radius, depth, entity knockback, effect density and camera movement scale with the impact and remain bounded for gameplay stability.
Custom visual pipeline
The addon contains nine dedicated particle shaders:
Structural shatter
Textured dust
Ground shockwave
Sparks
Contact flash
Boundary grit
Volumetric impact plume
Pressure wave
Faceted rubble
Dust and debris use Minecraft world collision. Effects attached to moving Sable sub-levels are simulated in local space so they travel with the structure instead of appearing at an unrelated point in the sky.
Built for multiplayer
Heavy impacts use a compact event packet. The server sends impact position, radius, severity and a deterministic seed once; each nearby client builds the full visual sequence locally.
Performance protection includes:
Distance-based visual LOD
Respect for Minecraft's All, Decreased and Minimal particle settings
Shared per-tick client particle budgets
A limit on concurrent impact sequences
Server-side effect and destruction budgets
Spatial and temporal effect deduplication
Deferred Sable mutations at safe tick boundaries
Client-only screens and shaders are isolated from dedicated-server code.
Configuration and commands
Operators can open the live configuration screen with:
/sable-dv config panel
The alias /sable config panel is also available.
Other commands:
/sable-dv on
/sable-dv off
/sable-dv config reset
The panel controls damage gates, self-damage, penetration, detach behaviour, shockwave radius, crater depth, knockback, epic impact effects, camera shake and particle density. Settings persist in config/sabledestructive-common.toml.
Commands and server-side panel changes require operator permission level 2.
# Sable: Destructive 2.2.0 — Destruction, Compatibility & Safety
Version 2.2.0 is a large stability, compatibility, balance and visual-effects update for Sable: Destructive. It completes the impact-system overhaul, makes explosions and collisions safer around Sable sub-levels, fixes snow-covered terrain, improves hard-material destruction, prevents several Sable lifecycle crashes and adds a supported API for other mod authors.
The result is a destruction system that is more physical and more spectacular under heavy impacts, while being substantially safer during ordinary gameplay, large explosions, level unloading and repeated collision events.
## Major highlights
- Fixed explosions and mine-triggered explosions crashing while scanning Sable plots.
- Fixed explosions producing sound while destruction of affected Sable blocks was skipped after an unsafe plot access.
- Fixed thin snow remaining suspended after the dirt, grass or other supporting terrain below it was destroyed.
- Fixed collision dust being spawned in Sable's hidden plot-storage space instead of the visible parent world.
- Fixed removed sub-levels continuing heat-map splitting and attempting to assemble blocks inside an already removed plot.
- Rebalanced high-toughness finite blocks so the 20–30 toughness range is no longer effectively immortal.
- Preserved meaningful armour behaviour for obsidian, netherite and reinforced materials.
- Improved heavy-impact flash, shockwave, debris, dust-plume, sound and camera feedback.
- Added strict server and client budgets so large destruction events scale down safely instead of flooding the tick or render loop.
- Added the public `SableDestructiveApi` integration surface for weapons, vehicles, explosives and other addons.
- Removed normal-shutdown diagnostic spam and filtered harmless Modrinth App launcher disconnects.
## Collision destruction and impact physics
- Rebuilt the break decision around a deterministic kinetic-energy and fracture-cost model.
- Impact calculations now account for:
- defender block mass;
- defender material strength and fracture toughness;
- real Sable body mass;
- attacker contact hardness;
- relative impact speed;
- reduced contact mass;
- impact-energy retention;
- the difference between known and unknown attacker materials.
- Fixed inconsistent Sable mass conversion and removed the former second application of `massScale`.
- Added a capped mass advantage. A huge construction still hits harder, but additional soft blocks cannot provide unlimited armour penetration.
- Added a physical low-speed safety floor. Small blocks dropped from ordinary heights bounce or stop instead of repeatedly drilling through terrain.
- Unknown contact materials are treated conservatively as ordinary material instead of inheriting the defender's hardness.
- Invalid or missing mass, speed and direction values are sanitized before entering the destruction queue.
- Soft attacking faces can damage themselves when they strike a significantly harder surface.
- Damage is block-by-block by default, avoiding the old long layer-shaped trenches.
- Optional penetration now spends actual remaining fracture energy one block at a time.
- Penetration is disabled by default, requires an extreme impact when enabled and is capped at two additional blocks.
- Optional cluster detachment is disabled by default and protected by parent, size, speed, cooldown and active-fragment limits.
- Detached fragments inherit safe motion, receive bounded separation and rebound impulses, and are explicitly woken in Sable's physics pipeline.
- Failed or unsafe detach operations fall back to a controlled VANISH result instead of leaving a half-assembled fragment.
## Material balance
- Rebalanced the ordinary finite toughness table so blocks above the stone band can actually fail under proportionate impacts.
- Materials in the former 20–30 toughness dead zone are substantially less resistant than before.
- Mid-strength stone and masonry remain tougher than dirt, snow, leaves and glass.
- Hard materials still require both sufficient speed and sufficient fracture energy; mass alone is not an automatic bypass.
- Extremely fast impacts can gradually relax the contact-material ratio for a known attacker, so finite materials do not become absolutely immortal.
- Unknown attackers cannot use a fabricated huge mass value as a reliable shortcut through the strongest material tiers.
- Obsidian, crying obsidian, respawn anchors, ancient debris, netherite and reinforced deepslate retain dedicated high-tier material entries.
- Bedrock, barriers, command blocks, structure infrastructure, portals and other administrative or immutable blocks remain protected.
- Modded blocks without a dedicated entry receive a bounded fallback based on vanilla hardness, explosion resistance and map-colour density.
- The material cache can be invalidated cleanly when configuration or registry-dependent values change.
## Snow and winter-biome behaviour
- Added dedicated fragile-snow classification for snow layers, snow blocks and powder snow.
- Added a snow-specific impact multiplier so light snow gives way before the terrain beneath it.
- Fixed moving Sable constructions passing through the visible snow cover while breaking only the dirt or grass block below.
- When a collision or shockwave removes a supporting terrain block, a thin `minecraft:snow` layer directly above it is now removed in the same tick.
- The support cleanup works in both the normal world and plot-local Sable destruction paths.
- Plot-local snow cleanup checks the exact plot bounds before accessing the embedded level, preserving compatibility with older Sable builds.
- Snow cleanup uses the same no-block-drop destruction policy and does not generate an extra vanilla explosion-particle event.
- Full snow blocks and powder snow are not blindly removed merely because a lower block changed; only unsupported thin cover receives the automatic cleanup.
## Explosions and mine compatibility
- Hardened the NeoForge explosion path used by TNT, creepers, end crystals, beds, respawn anchors and compatible modded explosives or mines.
- Explosion spheres are now clamped to each Sable plot's real local bounding box before `EmbeddedPlotLevelAccessor` is queried.
- Empty space outside a plot is never scanned through unsafe negative or unmapped plot chunk indices.
- Removed, missing and partially unloaded sub-levels are skipped safely.
- One broken or stale plot can no longer abort processing for every other Sable construction in the same explosion.
- Per-sub-level and per-outcome exception containment prevents an individual bad target from crashing the complete explosion event.
- Break candidates are collected first and processed from the explosion centre outward.
- A strict maximum-break budget prevents very large explosions from producing an unbounded amount of synchronous plot work.
- Internal explosions use configurable absorption while external explosions use distance-based energy falloff.
- VANISH outcomes remove the block without creating the vanilla block-item drop or duplicate break event.
- Container blocks still spill their inventory contents before being removed.
- DETACH outcomes now queue a real Sable physics fragment with an outward explosion impulse.
- If a fragment cannot be created safely, the result falls back to VANISH rather than silently doing nothing.
- Explosion visuals are transformed from plot-local coordinates to the actual parent-world position.
## Heavy impacts, flash and shockwave effects
- Heavy shockwaves now require a substantial falling body and confirmed contact with solid world terrain.
- Impact origin is resolved from the transformed lower centre of the Sable construction instead of an arbitrary storage coordinate.
- Crater radius, depth, debris, knockback and effect strength use bounded mass- and speed-based scaling.
- Craters are processed from the centre toward the rim, keeping their shape coherent if the server break budget is reached.
- Shockwave pressure uses a dedicated effective contact hardness rather than pretending the crater was made by a soft dirt projectile.
- Added a fast contact flash to make the first impact frame readable.
- Added separate dusty and translucent pressure fronts with different expansion speeds.
- Added physical-looking faceted rubble with gravity, world collision, bounce damping and delayed settling.
- Added a rising turbulent dust column and a delayed ground-hugging dust skirt.
- Added secondary debris and dust phases so giant impacts feel like one continuous event rather than a single flat particle burst.
- Added severity-scaled impact boom, low rumble and crater-crack sound layers.
- Added distance-attenuated camera-angle and FOV shake with a fast initial vibration followed by a slower rumble.
- Camera shake, cinematic effects, effect density, crater depth, radius and knockback remain configurable.
- A lightweight classic-effect fallback is used when the cinematic impact suite is disabled.
## Dust, particles and coordinate-space fixes
- Collision dust originating from a Sable storage position is now transformed into parent-world coordinates before it is sent to clients.
- Collision dust no longer becomes attached to the moving sub-level that caused the collision.
- Fixed dust appearing in the hidden Sable plot world or colliding with invisible plot geometry.
- Explicit sub-level effects that should move with a live construction still use plot-local coordinates and Sable particle tracking.
- Plot effect payloads are normalized from storage coordinates to valid local coordinates before transmission.
- Invalid or out-of-bounds plot particle positions are rejected instead of reaching client particle physics.
- Improved sub-level particle collision against floors and thin walls using actual block collision shapes.
- Missing client plot chunks or a removed client sub-level no longer crash the render thread.
- Fixed dust and grit settling or bouncing in the wrong coordinate space.
- Fixed particle-atlas handling that could make flash, dust and shockwave sprites look square, clipped or incorrectly centred.
- Added dedicated shader passes for pressure waves, volumetric plume particles and faceted rubble.
- The complete effect suite now uses dedicated shatter, dust, shockwave, spark, flash, grit, pressure, plume and rubble rendering.
## Performance and multiplayer
- Collision callbacks only enqueue validated lightweight contact records; destructive world changes remain on the server tick.
- The break queue is lock-free and uses an atomic size counter.
- Added an epoch-based contact deduplication ring to collapse repeated physics callbacks for the same collision.
- Added per-physics-step offer limits, total queue capacity and per-server-tick drain budgets.
- Queue entries belonging to an unloading level are removed without disturbing other dimensions.
- Pending detaches are also cleared when their level unloads or the server stops.
- Repeated nearby break effects use spatial and temporal deduplication to reduce particle and sound stacking.
- VANISH effects have a hard per-tick limit and degrade to reduced audio when the visual budget is exhausted.
- Heavy impacts send one compact deterministic event to each nearby player instead of hundreds of individual particle packets.
- Clients expand that event locally using a shared seed.
- Particle density scales with distance, the configured effect scale and Minecraft's `All`, `Decreased` or `Minimal` particle setting.
- Added a shared per-tick client spawn budget.
- Simultaneous long-lived heavy-impact sequences are capped.
- Players outside the effect range do not receive the impact payload.
- Dedicated servers do not load client-only particle, shader, camera or configuration-screen classes.
## Crash and lifecycle safety
- Fixed `Sub-level assembly attempted inside plot of already removed sub-level`.
- Added a compatibility mixin that cancels Sable heat-map `tick()` and `split()` operations after their owner sub-level has been removed.
- Added repeated `isRemoved()` checks before plot access, cluster assembly, fragment registration and final impulse application.
- Added a short break-immunity window for newly detached fragments to prevent immediate recursive re-splitting.
- Despawn and level-unload cleanup clears tracked fragments, queues, effect state and shockwave state.
- Explosion and collision handlers contain failures locally and continue processing safe work.
- High error rates temporarily disable destructive processing for 60 seconds instead of allowing a runaway failure loop.
- Destruction automatically resumes after the emergency-disable window expires.
- Normal game shutdown no longer creates `sable-destructive-shutdown-*.log`.
- Genuine uncaught failures create at most one `sable-destructive-emergency-*.log` per process.
- Emergency reports retain the useful thread, uptime, queue, dedup, processed-event and error-rate counters.
- Harmless Modrinth App `Theseus RPC` `SocketException` / `UncheckedIOException` disconnects are recognized as external launcher shutdown noise and ignored.
- A failed report write can be retried by a later genuine emergency.
## Block removal and inventory safety
- Centralized collision, shockwave, explosion and public-API block removal through `ImpactBlockBreak`.
- Blocks destroyed by Destructive do not drop a duplicate block item.
- Vanilla level event `2001` is avoided, preventing duplicate vanilla explode-block dust on top of the custom effect.
- Block entities are removed defensively.
- Randomizable containers unpack their loot table before destruction.
- Chests and other containers spill and clear their contents instead of deleting inventory data.
- World and plot-local removal share the same safety rules.
- Thin snow support cleanup is now part of this central path, so future integrations receive the fix automatically.
## API and compatibility for other mod authors
- Added `com.destroynautics.sabledestructive.api.SableDestructiveApi`.
- Added stable API version constant `API_VERSION = 2_2_0`.
- Added `isEnabled()` for checking whether destructive processing is active.
- Added `evaluateImpact(...)` for obtaining the complete deterministic break verdict.
- Added `canBreak(...)` for simple material, mass and speed checks.
- Added `destroyWorldBlock(...)` for safe no-block-drop world destruction.
- Added `destroySubLevelBlock(...)` for safe plot-local destruction using Sable local coordinates.
- Other mods no longer need to access the internal break queue, explosion handler or plot-storage conversion details.
- The shared destruction API preserves container contents, protected blocks, snow-support cleanup and the common no-duplicate-particle policy.
- Public integration is intended for weapon, mine, bomb, vehicle and structural-damage addons.
## Configuration and defaults
- Kept persistent configuration in `config/sabledestructive-common.toml`.
- The `/sable-dv config panel` exposes the important gameplay and visual controls.
- Layer penetration and multi-block detach ship disabled by default for stable block-by-block damage.
- Explosion handling, shockwave terrain damage, falling dust and heavy-impact effects can be controlled independently.
- Material ratio, self-damage, queue capacity, per-tick budgets, fragment limits and safety ceilings remain tunable.
- Added a safe world-space collision-dust default.
- Snow receives a dedicated default impact multiplier without weakening the supporting terrain.
## Compatibility
- Minecraft 1.21.1
- NeoForge 21.1.243 or newer
- Sable 2.0.3 or newer
- Java 21
- Client, integrated server and dedicated server supported
- Mod version: `2.2.0`
- Public API version: `2_2_0`
## Verification
- Clean Gradle build completed successfully.
- 7 deterministic impact-physics regression tests passed.
- 0 test failures.
- 0 test errors.
- Final artifact: `sabledestructive-2.2.0.jar`.
- SHA-256: `368C8DC576EF70A7803B4DF9DB46C6C4CA01F093AD04FA0243E714A10A717C43`.
## Upgrade notes
- Remove the previous Sable: Destructive JAR before installing 2.2.0.
- Install only one version of Sable: Destructive.
- Fully restart Minecraft or the dedicated server after replacing the file.
- Do not hot-swap the mod while a world or server is running.
- Existing configuration files remain supported; review the new defaults if upgrading from an older aggressive penetration setup.
---
# Sable: Destructive 2.1.0 — Impact Overhaul
Version 2.1.0 rebuilds collision damage, heavy landings and destruction effects around a safer material-and-energy model. Small accidents remain small, while genuinely massive impacts can tear structures apart, fracture ordinary hard materials and leave a convincing crater.
## Highlights
- Reworked damage into block-by-block structural failure instead of long layer-shaped trenches.
- Added cinematic giant-impact sequences with a contact flash, expanding shock fronts, ballistic rubble, an upward dust plume and delayed settling dust.
- Added three new custom shaders for pressure waves, volumetric dust plumes and faceted rubble. The mod now uses nine dedicated particle shaders.
- Added distance-attenuated camera and FOV shake with a fast impact kick followed by a slower ground rumble.
- Added circular, severity-scaled craters and stronger heavy-impact pressure damage to world terrain.
- Added client-side LOD and compact event networking to keep large effects practical in multiplayer.
## Damage and material balance
- Replaced the previous mass heuristic with a deterministic kinetic-energy, reduced-mass and material-toughness model.
- Added a low-speed safety floor: dropping a normal stone block from roughly two blocks no longer makes it drill toward the bottom of the world.
- Disabled layer penetration by default. Optional extreme-impact penetration requires at least 20 m/s and is capped at two additional blocks.
- Disabled multi-block cluster detach by default so normal damage progresses one contact block at a time.
- Added a capped mass advantage. Adding more grass or another soft material no longer turns it into an armour-piercing projectile.
- Added attacker self-damage when a soft contact face hits a much harder defender.
- Rebalanced every finite ordinary toughness tier. Stone, metal, obsidian, netherite and reinforced blocks can fail under a proportionate impact instead of behaving as immortal blocks.
- Bedrock, barriers, command/structure blocks and portal infrastructure remain intentionally protected.
- Fixed Sable body-mass conversion and removed an accidental second application of `massScale`.
- Fixed explosion DETACH so it creates an actual physics fragment instead of silently deleting the block.
## Giant-impact effects
- Heavy landings now require confirmed contact with solid world terrain.
- Impact origin is calculated from the transformed bottom centre of the falling Sable body.
- Added a fast dusty shock ring and a separate translucent pressure front.
- Added physical rubble with gravity, world collision and damped ground bounces.
- Added a long-lived rising plume with turbulent drift, expansion and gradual opacity loss.
- Added delayed skirt dust and secondary fragments after the initial collision.
- Added severity-scaled boom, low rumble and crater-crack sound layers.
- Fixed shader atlas handling that could make dust and shockwave sprites appear square, clipped or incorrectly centred.
- Dust and grit now collide and settle in the correct coordinate space, including particles attached to moving Sable sub-levels.
## Performance and multiplayer
- A heavy impact now sends one compact deterministic event to each nearby player instead of hundreds of individual server particle packets.
- Particle density scales with distance and the player's Minecraft particle setting.
- Added a shared per-tick client spawn budget and a limit on simultaneous impact sequences.
- Existing server FX budgets, spatial deduplication and destruction queue limits remain active.
- Dedicated servers do not load client-only shader or screen classes.
## Configuration
The `/sable-dv config panel` screen now includes controls for:
- Epic heavy-impact effects
- Camera shake enable/disable
- Camera shake strength
- Impact FX density
- Maximum shockwave radius up to 48 blocks
- Crater depth and knockback
- Material gates, self-damage and optional penetration
Settings remain persistent in `config/sabledestructive-common.toml`.
## Compatibility and installation
- Minecraft 1.21.1
- NeoForge 21.1.235 or newer
- Sable 2.0.3 or newer
- Java 21
- Client and dedicated-server compatible
Remove the previous Sable: Destructive JAR, install `sabledestructive-2.1.0.jar`, and fully restart the game or server. Do not hot-swap this update.
## Verification
- Clean Gradle build completed successfully.
- 7 deterministic physics regression tests passed.
- 0 test failures and 0 test errors.
Version 2.1.0 rebuilds collision damage, heavy landings and destruction effects around a safer material-and-energy model. Small accidents remain small, while genuinely massive impacts can tear structures apart, fracture ordinary hard materials and leave a convincing crater.
## Highlights
- Reworked damage into block-by-block structural failure instead of long layer-shaped trenches.
- Added cinematic giant-impact sequences with a contact flash, expanding shock fronts, ballistic rubble, an upward dust plume and delayed settling dust.
- Added three new custom shaders for pressure waves, volumetric dust plumes and faceted rubble. The mod now uses nine dedicated particle shaders.
- Added distance-attenuated camera and FOV shake with a fast impact kick followed by a slower ground rumble.
- Added circular, severity-scaled craters and stronger heavy-impact pressure damage to world terrain.
- Added client-side LOD and compact event networking to keep large effects practical in multiplayer.
## Damage and material balance
- Replaced the previous mass heuristic with a deterministic kinetic-energy, reduced-mass and material-toughness model.
- Added a low-speed safety floor: dropping a normal stone block from roughly two blocks no longer makes it drill toward the bottom of the world.
- Disabled layer penetration by default. Optional extreme-impact penetration requires at least 20 m/s and is capped at two additional blocks.
- Disabled multi-block cluster detach by default so normal damage progresses one contact block at a time.
- Added a capped mass advantage. Adding more grass or another soft material no longer turns it into an armour-piercing projectile.
- Added attacker self-damage when a soft contact face hits a much harder defender.
- Rebalanced every finite ordinary toughness tier. Stone, metal, obsidian, netherite and reinforced blocks can fail under a proportionate impact instead of behaving as immortal blocks.
- Bedrock, barriers, command/structure blocks and portal infrastructure remain intentionally protected.
- Fixed Sable body-mass conversion and removed an accidental second application of `massScale`.
- Fixed explosion DETACH so it creates an actual physics fragment instead of silently deleting the block.
## Giant-impact effects
- Heavy landings now require confirmed contact with solid world terrain.
- Impact origin is calculated from the transformed bottom centre of the falling Sable body.
- Added a fast dusty shock ring and a separate translucent pressure front.
- Added physical rubble with gravity, world collision and damped ground bounces.
- Added a long-lived rising plume with turbulent drift, expansion and gradual opacity loss.
- Added delayed skirt dust and secondary fragments after the initial collision.
- Added severity-scaled boom, low rumble and crater-crack sound layers.
- Fixed shader atlas handling that could make dust and shockwave sprites appear square, clipped or incorrectly centred.
- Dust and grit now collide and settle in the correct coordinate space, including particles attached to moving Sable sub-levels.
## Performance and multiplayer
- A heavy impact now sends one compact deterministic event to each nearby player instead of hundreds of individual server particle packets.
- Particle density scales with distance and the player's Minecraft particle setting.
- Added a shared per-tick client spawn budget and a limit on simultaneous impact sequences.
### - Existing server FX budgets, spatial deduplication and destruction queue limits remain active.
### - Dedicated servers do not load client-only shader or screen classes.
###
### ## Configuration
###
### The `/sable-dv config panel` screen now includes controls for:
###
### - Epic heavy-impact effects
### - Camera shake enable/disable
### - Camera shake strength
### - Impact FX density
### - Maximum shockwave radius up to 48 blocks
### - Crater depth and knockback
### - Material gates, self-damage and optional penetration
###
### Settings remain persistent in `config/sabledestructive-common.toml`.
###
### ## Compatibility and installation
###
### - Minecraft 1.21.1
### - NeoForge 21.1.235 or newer
### - Sable 2.0.3 or newer
### - Java 21
### - Client and dedicated-server compatible
###
### Remove the previous Sable: Destructive JAR, install `sabledestructive-2.1.0.jar`, and fully restart the game or server. Do not hot-swap this update.
###
### ## Verification
###
- Clean Gradle build completed successfully.
- 7 deterministic physics regression tests passed.
- 0 test failures and 0 test errors.
### Fixes
- **Crash:** `Sub-level assembly attempted inside plot of already removed sub-level` — despawn now clears the plot with `destroyAllBlocks()` then removes via the container; detach refuses break-immune / already-removed parents and vanishes leftover blocks instead of restoring into a dying plot
- **Dust / grit:** particles no longer appear as a speck in the sky or vanish instantly — plot-local coords are sent over the wire, the client embeds them into the live sub-level pose, and sim runs in local space with visible alpha
- Falling-dust rim sampling uses center-of-mass instead of the empty plot AABB
### Changes
- Version bumped to **2.0.1**
- Full Modrinth / README description restored and updated for 2.0.x (commands, Sable 2.0.3+ requirement)
### Notes
- Replace the old jar completely and restart the game (hot-swap is not enough after the despawn path change)
- Requires **Sable 2.0.3+** on NeoForge **21.1.235+** / Minecraft **1.21.1**
Built against Sable 1.2.2 (the API surface we use is stable from
1.1.3 → 1.2.2 — no source changes required, this is a recompile +
diagnostics release).
What's new
- Startup self-check. The very first INFO line in the log now reads
`[Sable: Destructive] addon=1.7.2 sable=1.2.2` (or `sable=NOT LOADED`
with a loud warning if Sable is missing). Future API-mismatch
reports become a two-line paste instead of a full log dump.
- `/sable-dv diag` — live counters for "is the shockwave alive?":
* Server waves emitted + packets actually sent
* BreakQueue throughput (offered / processed / pending / dropped
by capacity vs. dedup)
* SubLevelMassResolver cache hit/miss/fallback rates
* Detected Sable runtime version
The command also prints a hint based on what it sees:
* Zero waves → magnitude / mass gate is filtering everything.
Lower `shockwaveMinMagnitude` or `shockwaveMinAttackerMassUnits`.
* Waves but zero packets → no players inside
`shockwaveClientHorizonBlocks`. Stand closer or raise it.
* Both non-zero → server is healthy; if the client sees nothing,
install the addon CLIENT-side too.
- Compiled against Sable 1.2.2 (`libs/sable-neoforge-1.21.1-1.2.2.jar`).
The 1.1.3-only `compileOnly`/`localRuntime` entries in `build.gradle`
were swapped over so the IDE dev-runtime now matches the version
most users have installed via Modrinth.
Crash report note (NOT Sable: Destructive)
- The Create / Registrate `chocolate_bucket` NPE crash users have
been seeing is a known Create 6.0.10 bootstrap-ordering bug. Our
mod is not in that stack trace — we don't subscribe to
`RegisterEvent` or touch Create, Registrate, items, fluids, or
advancements. Typical fix: remove duplicate Aeronautics jars
(bundled + standalone), or redownload the Create jar if corrupt.
Requirements
- Minecraft 1.21.1, NeoForge 21.1.227+, Sable 1.1.3 or newer (tested
on 1.2.2 — earlier 1.1.x still loads at runtime, only the
registered Sable APIs we use need to exist).
## MIT License
Hotfix for "модовые блоки не ломаются" — the callback was silently
skipping every block with an attached `BlockEntity`, which is the
overwhelming majority of modded machinery (Create cogwheels and
shafts, Mekanism cables, Applied Energistics buses, every chest /
furnace / hopper, etc.). That made the addon visually a no-op
against most non-vanilla builds.
Why it was skipped originally
- Pre-1.6.1 the callback assumed BE teardown was always fragile —
Sable's sub-level assembler doesn't preserve BE NBT cleanly, and
peeling a half-built contraption can corrupt its kinetic-network
state on the modded side.
What changed
- `allowBlockEntityBreaks` (new, default `true`). BE-bearing blocks
ARE now broken on contact. The block is removed via an explicit
`level.removeBlockEntity(pos)` BEFORE the `setBlock(AIR)`, so the
BE's saved NBT is discarded cleanly and no vanilla on-remove
side-effect can throw out of the callback.
- `allowBlockEntityDetach` (new, default `false`). Even when BE
breaks are allowed, the outcome is forced to VANISH — never
DETACH. Reason: Sable's assembler doesn't carry BE NBT into the
new sub-level, so peeling a Create gearbox would instantly
desync its kinetic network. VANISH discards the BE cleanly. Set
to `true` if you want the experimental "peel BEs too" behaviour
(expect cosmetic issues on Create/Mekanism).
- `safeSetAir` now explicitly removes any attached BlockEntity
before airing the cell. Catches any throwable from the BE's own
remove handler (Create kinetic teardown, Mekanism cable rebuild,
etc.) so a third-party mod's on-remove bug can never escape into
Sable's native bridge.
Compatibility
- Set `allowBlockEntityBreaks=false` in
`config/sabledestructive-common.toml` to restore the pre-1.6.1
"skip every BE block" behaviour.
- All other 1.6.0 knobs and behaviour unchanged.
Requirements
- Minecraft 1.21.1, NeoForge 21.1.227+, Sable 1.1.3+
MIT License
The whole break/shockwave pipeline now reads each Sable sub-level's
ACTUAL mass (in kg) from Sable's own `MassData` tracker instead of
treating every attacker as a hard-coded 2000 kg "default ship". Per
the Sable wiki, every block carries a `sable:mass` property (kpg);
`ServerSubLevel#getMassTracker().getMass()` returns the sum that the
physics pipeline itself uses for Rapier. We just read it.
This single change fixes the long-standing complaint that "a tiny
flying chunk feels exactly as heavy as a 5000-block ship": below,
the same 12 m/s impact now produces three very different outcomes
depending on the attacker's real mass.
What is new
- `SubLevelMassResolver` — single source of truth for per-sub-level
mass. O(1) per call (queries `ServerSubLevel#getMassTracker()`),
per-tick identity-keyed cache, defensive fallback to
`defaultAttackerMassKg` on any Sable-side failure. Hard-capped at
`subLevelMassHardCapKg = 1e8 kg` to prevent a corrupted physics
tick from making the energy budget infinite.
- Mass-aware kinetic-energy budget. `BreakResolver.shouldBreakState`
was already a kinetic-energy formula, but it was always fed 2000
kg. Now it sees the real attacker mass, so:
* A 100 kg flying cobblestone at 12 m/s = 7 200 J → bounces off
stone (budget 18 kJ).
* A 50 t small ship at 12 m/s = 3.6 MJ → punches stone wide open.
* A 500 t fortress at 6 m/s = 9 MJ → grinds through obsidian.
The reduced-mass term µ = m1·m2/(m1+m2) means a feather-light
attacker still cannot pulverize a heavy defender — the math
collapses to the attacker's own KE budget.
- Mass-aware structural-toughness gate. The "soft attacker can't
pierce hard defender" rule (`attackerToughnessRatio`) now has a
**mass relief** factor: the required attacker toughness is scaled
by `sqrt(massToughnessReferenceKg / realMass)`, floored at
`massToughnessReliefFloor`. A 100 t crusher made of packed dirt
WILL pulverize stone purely from inertia; a thrown dirt clump
won't. Defaults: `massToughnessReferenceKg = 4000`,
`massToughnessReliefFloor = 0.1` (so at most a 10× relief — a
fully soft Jell-O sub-level can never bypass the gate entirely).
- Shockwave magnitude now uses the same real mass. The bespoke
flood-fill (`computeAttackerMassUnits`, O(N) up to 1500 blocks per
emit) is no longer the primary path — when `useSubLevelMass=true`
we feed Sable's mass tracker × `shockwaveAvgToughnessUnits` (= 120,
i.e. V_STONE × 10) so all existing magnitude thresholds keep their
meaning. Flood-fill remains as the fallback for the unlikely case
where the mass tracker has not been built yet. Net result:
shockwave emission is now O(1) per impact and reflects the real
ship size, not a 6-neighbour sample of it.
- New persistent config knobs (TOML hot-reload as usual):
* `useSubLevelMass` (bool, default true)
* `subLevelMassHardCapKg` (kg, default 1e8)
* `massToughnessReferenceKg` (kg, default 4000)
* `massToughnessReliefFloor` (×, default 0.1)
* `shockwaveAvgToughnessUnits` (units, default 120)
What is fixed
- "Two tiny dirt blocks shouldn't break obsidian by being heavy" —
was actually still happening for SHIP-vs-OBSIDIAN because the
callback was hard-coding 2000 kg. With real mass, a 200 kg dirt
fragment now correctly fails the gate AND fails the energy budget.
- Heavy ships landing softly used to bounce indefinitely because
every contact was rated at 2000 kg @ low speed = 144 kJ, below
every threshold. They now report their real mass, so a 100 t
ship setting down at 4 m/s = 800 kJ punches through dirt/wood as
expected.
- Shockwave was firing inconsistently for big builds because the
flood-fill capped at `shockwaveMassFloodCap = 1500` blocks
underestimated ships larger than that. The real mass tracker has
no such cap.
Backward compatibility
- `useSubLevelMass=false` restores the pre-1.6.0 behaviour exactly
(hardcoded `defaultAttackerMassKg`, flood-fill for shockwave).
- All existing config keys preserved with the same defaults.
- `BreakResolver.shouldBreakState(...)` signature unchanged.
- `ShockwaveEffect.emit(level, center, energy)` overload kept; a
new `emit(level, center, energy, attackerMassKgHint)` overload is
preferred by callers that already have the resolved mass.
Requirements
- Minecraft 1.21.1
- NeoForge 21.1.227+
- Sable 1.1.3+ (uses `ServerSubLevel#getMassTracker()`)
Credits
- Code: Xylos_Official
- Visuals: Viaquelt
- Built on top of Sable by ryanhcode
# MIT License
A major rework of the damage pipeline and the shockwave effect.
This release responds to two specific 1.4.0 reports:
1. "блоки АБСОЛЮТНО все пропадают" — in DETACHING mode (the
default), a routing bug silently turned almost every
contact into a VANISH instead of a real sub-level peel.
2. "звуковые волны после 1.4.0 пропали" — the shockwave was
gated behind `mode != DETACHING`, so with the default mode
it never fired at all.
Both are fixed, and the underlying systems were reworked rather
than patched.
What is new
- DETACH-FIRST damage. Block contacts now peel from the parent
sub-level into a fresh physics body by default. VANISH is
reserved for genuinely tiny debris (and for the explicit
`/sable-dv mode delete`). The `chanceDetach` default is now
0.92 / `chanceVanish` 0.08.
- World terrain is no longer touched in DETACHING mode. In 1.4.0
a routing bug sent the world side of every contact pair down a
branch that VANISH'd the terrain — that was the "all blocks
disappear" report. The actual mechanic:
* Sable invokes `BlockSubLevelCollisionCallback` ONLY for
sub-level blocks (never for world terrain), so there is no
world-side classification to do. The earlier 1.5.0 attempt
added an explicit `getContaining(level, plotPos)` check
that always returned `null` because plot-region coords are
disjoint from world coords — that mis-classified 100% of
contacts as "world terrain" and silently skipped them, so
destruction stopped happening altogether. Removed.
* DETACHING mode now reliably peels every qualifying contact.
* DELETE / DELETE_DETACHING are unchanged.
- Real shockwave model. Triggered only when a BIG, HEAVY object
lands at speed — not by small bumps. Three independent gates:
* Approach speed ≥ `shockwaveMinApproachSpeed` (default 12 m/s)
* Impact energy ≥ `shockwaveMinEnergy` (default 2 MJ)
* Attacker mass ≥ `shockwaveMinAttackerMassUnits` (default
400 000 — equivalent to ~200 stone blocks of summed
mass × toughness around the contact point)
* Combined magnitude ≥ `shockwaveMinMagnitude` (default 1.5 MJ)
A single cobble flying around can never produce a wave. A
five-thousand-block stone ship hitting the ground at 6 m/s does.
- Shockwave fires in EVERY mode. In 1.4.0 it was buried inside
the inertial-penetration block, which itself ran only when
`mode != DETACHING`. The emission is now outside that gate so
big landings produce dust + a heavy thud regardless of mode.
- Shockwave visuals/audio optimized. One radial dust burst
(replacing three expanding rings), a rising dust column at
the impact point, a single heavy "thud" sound — instead of
three layered sand/wool/explosion sounds. Per-source dedup
window, per-second global rate-limit, and a per-tick particle
budget so back-to-back impacts cannot tank FPS.
- Magnitude drives radius AND ceiling. Radius scales as
`cbrt(magnitude / reference) × radiusMultiplier`. The
toughness ceiling on what the wave can break scales with the
same factor and falls off linearly to the radius edge, so a
small wave only rips leaves and dirt while a giant landing
carves a real crater into stone.
What is fixed
- Bedrock and other unbreakable blocks are now actually safe
inside sub-levels. The DETACHING branch used to bypass every
break gate, which meant a physics bedrock could be peeled by
any contact. The callback now applies four universal gates
(in EVERY mode, DETACHING included):
* Reject if defender toughness is infinite (bedrock, barrier,
command block, end portal frame, structure block, …).
* Reject if vanilla `getDestroySpeed < 0`.
* Reject if attacker toughness × `attackerToughnessRatio` is
below defender toughness (a 20-unit block cannot break a
120-unit block by ramming it at any speed — the soft
attacker erodes its own contact face instead).
* Reject if approach speed × `collisionStrengthMultiplier` is
below the defender's break-speed threshold.
The shockwave damage pass now also skips infinite-toughness
blocks, so a giant landing never carves a hole in bedrock.
- Cluster detach no longer produces long strips. The BFS used a
FIFO deque + shuffled directions, so on a flat 1-block-thick
hull the only available neighbours were tangential and the
chunk grew along the surface as a line — the user's "ломается
полосками длинным" report. The planner now uses a distance-
ordered priority queue and a hard Chebyshev radius cap of
`ceil(cbrt(targetSize))` around the seed. Clusters stay
spherical even on thin surfaces, and a single-block contact
can never spawn a 6-long row.
- Shockwave gates relaxed back to sane gameplay levels. The
previous defaults (12 m/s, 2 MJ, 400 000 mass-units, 1.5 MJ
magnitude) were tuned for the *broken* pre-fix 1.5.0 build
and made the wave effectively unreachable. New defaults:
* `shockwaveMinApproachSpeed` = 5 m/s
* `shockwaveMinEnergy` = 100 000 J
* `shockwaveMinAttackerMassUnits` = 50 000 (~25 stone blocks)
* `shockwaveMinMagnitude` = 200 000
Small bumps still don't trigger because the per-source dedup
window (250 ms), per-second cap (6/s), and real flood-fill of
the attacker's mass × toughness filter out everything that
isn't a substantial body landing.
- Shockwave decision no longer pre-gated in the callback. The
callback used `defaultAttackerMassKg` (2000 kg) for the pre-
energy check, which never crossed the threshold at gameplay
speeds, so `ShockwaveEffect.emit()` was never called. The
pre-gate is removed; the effect's own real-mass gates decide.
- Shockwave dust completely redone. Old build used POOF + a
single block-dust grain per ring point — opaque and
short-lived. New build:
* Radial low-altitude burst pushed outward with small
outward velocity (CLOUD particles mixed with tinted
ground-coloured BLOCK dust).
* A tall, narrow, slowly-rising dust column at the impact
point, scaling with radius — the "поднимается вверх"
mushroom you wanted.
* CLOUD particles render with naturally semi-transparent
edges (~25% alpha) and live 2–3 s before fading, giving
the "медленно оседает" look without us having to ship a
custom particle texture.
The dust now reads as real impact dust rather than the old
three-band ring spam.
- DETACHING mode never destroys structural blocks via the
shockwave. The wave still emits visuals + sound in DETACHING,
but the damage pass is foliage-only (plants and leaves) —
consistent with "DETACHING = nothing is destroyed".
- `minBreakSpeed` raised 6 → 10 m/s. The old default let tiny
bumps register as full break candidates, which combined with
the missing toughness gate produced the "блоки ломаются от
малого шороха" report. Combined with the new toughness gate
above, light contacts are now properly ignored.
- Toughness tooltip is now translatable. The F3+H "Toughness:
N units" line uses `Component.translatable` and ships
with eight languages: English, Russian, German, Spanish,
French, Portuguese (Brazil), Japanese, and Simplified Chinese.
Previous 1.5.0 fixes (kept):
- DETACHING world-side regression fixed (see above).
- Per-tick detach drain budget corrected (÷20+1).
- Inertial chain cursor sync.
- `CONSECUTIVE_ERRORS` → AtomicInteger.
- Lifecycle hooks clear ShockwaveEffect + VanishEffect caches.
Compatibility
- Old 1.x worlds load as-is. New 1.5.0 shockwave fields are
added to the TOML on next save (reflective config — no manual
migration needed).
- Mode names unchanged: `delete`, `detaching`, `delete-detaching`.
Default still `detaching`.
- Addon API unchanged; `API_VERSION` remains 1.
Requirements
- Minecraft 1.21.1
- NeoForge 21.1.227+
- Sable 1.1.3+
Credits
- Code: Xylos_Official
- Visuals: Viaquelt
- Built on top of Sable by ryanhcode
# MIT License
The command `/sable-dv mode <name>` switches the behavior of the collision system as a whole. The default mode is now **detaching**.
What is there
- `/sable-dv mode delete` - blocks only break (VANISH). No new sub-levels. The inertial chain works, and the world breaks through VANISH.
- `/sable-dv mode default` — alias to `detaching` (new default).
- `/sable-dv mode detaching` — **new default behavior**.
The hit detaches the block from the parent sub-level and spawns
a separate sub-world that inherits the speed and flies apart
in different directions. **Nothing is destroyed** — the pieces are physically
detached. Self-damage and inertial chain are disabled.
The world (terrain) breaks through VANISH (the world cannot be torn off as a sub-level).
- `/sable-dv mode delete-detaching` — combo: the starting block
detaches, the inertial chain additionally breaks the blocks deeper. Maximum chaos.
What is fixed
- **Shockwaves (shockwave)** no longer trigger at every sneeze. Now there are two independent thresholds:
- Minimum approach speed (`shockwaveMinApproachSpeed`,
default **18 m/s**) - cuts off settle/jitter contacts.
- Minimum energy (`shockwaveMinEnergy`, default
**8 MJ** instead of 250 kJ) - cuts off light impacts.
- The shockwave system itself is now **disabled by default**
(`shockwaveEnabled = false`). To enable it, use `/sable-dv set
shockwaveEnabled true`.
- **Epic Shatter on Impact** - A boulder thrown into a mountain now really shatters:
- On a hard impact, the cluster collapses to single blocks
(small pieces instead of a single large brick).
- Each broken piece has a random spread along
all axes + a random rotation, scaled by the
approach velocity.
- Kick limits raised: `detachKickScale 0.4 → 1.5`,
`detachMaxKickSpeed 6.0 → 25.0`.
- New parameters `detachShatterScatter` (default 6.0) and
`detachSpinScatter` (default 6.0) - adjustable scatter
and spin.
What is removed
- The typo `delete-detachingg` is no longer accepted. Only
canonical names: `delete`, `default`, `detaching`,
`delete-detaching`.
Compatibility
- Old 1.3.0 worlds are loaded as is. If TOML had
`collisionMode = "default"` — behavior is now `detaching`
(by new default).
- Mod API (Addon API) has not changed, API_VERSION remains 1.
Requirements
- Minecraft 1.21.1
- NeoForge 21.1.227+
- Sable 1.1.3+
Authors
- Code: Xylos_Official
- Visual part: Viaquelt
- Based on Sable by ryanhcode
# License MIT