
Sable: Destructive
Sable: Destructive makes Sable physics blocks actually break. Real kinetic energy, inertial penetration, density-aware self-damage, radial shockwaves on heavy hits — fast hammers dig deep into dirt, soft hammers shatter against stone, big drops radiate.
Real Shockwaves & Detach-First Damage
Список изменений
A major rework of the damage pipeline and the shockwave effect. This release responds to two specific 1.4.0 reports:
- "блоки АБСОЛЮТНО все пропадают" — in DETACHING mode (the default), a routing bug silently turned almost every contact into a VANISH instead of a real sub-level peel.
- "звуковые волны после 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). ThechanceDetachdefault is now 0.92 /chanceVanish0.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
BlockSubLevelCollisionCallbackONLY 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 explicitgetContaining(level, plotPos)check that always returnednullbecause 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.
- Sable invokes
-
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.
- Approach speed ≥
-
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 ×
attackerToughnessRatiois 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 ×
collisionStrengthMultiplieris 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/sshockwaveMinEnergy= 100 000 JshockwaveMinAttackerMassUnits= 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, soShockwaveEffect.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".
-
minBreakSpeedraised 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.translatableand 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 stilldetaching. - Addon API unchanged;
API_VERSIONremains 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
