Kyokalith

Buried ores are decoys until first exposed. Beats X-Ray, freecam & seed maps. No packets, no scans.
Back to Files

Kyokalith-1.3.5.jar

File nameKyokalith-1.3.5.jar
Uploader
tinyyanatinyyana
Uploaded
Jul 25, 2026
Downloads
7
Size
216.9 KB
File ID
8505797
Type
R
Release
Supported game versions
  • 26.2
  • 26.1.2
  • 26.1.1
  • 26.1

What's new

[1.3.5] - 2026-07-25

Fixed

  • Silk Touch'd eligible ore no longer refuses to stack. EligibleOrePdc.tag() stamped a fresh random UUID into the ItemStack's PDC on every call, so any two otherwise-identical eligible ore items always had different meta and could never merge — each Silk Touch break sat in the inventory as its own 1-count stack. The per-item token_id is gone from the ItemStack; eligible ore now stacks normally whenever oreType/origin_world/origin_epoch match, matching the spec's "eligibility follows the ItemStack" model. token_id still exists as a debug-only column on the eligible_placed_ores DB row, generated fresh at placement time instead of carried from the item.

[1.3.4] - 2026-07-25

Fixed

  • TNT now authenticates the destroyed volume, not only the new crater surface. Before Bukkit creates drops, accepted explosions deterministically lock visible natural-ore entrances first, then resolve every base/decoy block in blockList and every newly exposed neighbor. A buried decoy directly targeted through X-Ray therefore becomes its resolved base before destruction, while real hits inside the blast volume still produce vanilla drops.
  • Explosion batches are deterministic and atomically visible. Coordinates are processed in stable world/x/y/z order. All lock batches in one event share a 4,096-row hard budget, and block-type changes are deferred until every required batch succeeds. SQLite failure or budget exhaustion cancels the event without leaving partial world mutations; ordinary misses still write nothing.

Calibration

  • Radius-4 TNT crater sampling counts both destroyed-volume hits and new-surface hits. Distinct encounters per 100 blasts at critical layers: coal 36.328, iron 30.469, copper 28.516, gold 19.922, redstone 29.688, lapis 21.094, diamond 10.547, emerald 3.516, quartz 59.375, Nether gold 34.375, ancient debris 5.469.
  • The bundled ore configuration is unchanged from 1.3.3. The TNT regression fixes event semantics; it does not increase total density.

Verification

  • ./gradlew test: 78 tests passed, including TNT destroyed-volume/surface encounter bands and the 4,096-row event budget alongside all 1.3.3 geometry, density, migration, and failure-rollback regressions.
  • The previously shipped 1.3.3 JAR was reloaded successfully on localhost Paper 26.2 before the TNT change. A final 1.3.4 TNT-drop runtime fixture was attempted but blocked by the desktop tool's external-execution quota; it remains explicitly listed in the test handoff and is not claimed as passed.
  • Production deployment was not performed.

[1.3.3] - 2026-07-24

Fixed

  • Visible vanilla ore now opens a real, bounded vein instead of erasing the ore behind it. v1.3.2 treated an adjacent buried vanilla ore as an independent decoy; a resolver miss changed it to stone before exposure. A player could therefore see and mine the surface ore, then find no vein underneath. The first player break of an already-visible, unlocked natural ore now creates one salt-protected, face-connected continuation whose target size is the ore's configured vein_size. Its full result is locked in one batch before exposure; breaking locked members cannot seed another continuation.
  • Seed maps still cannot predict the continuation. The visible vanilla block is only an authenticated entrance. Hidden continuation order and size use the private Kyokalith salt, not the vanilla ore component or world seed. No unexposed block is changed or sent differently before first exposure.
  • Every continuation has a sealed endpoint. The salt-grown shape is capped by vein_size_max, Chebyshev radius 4, and a directly adjacent original-ore stop frontier. At most 7 × vein_size rows are written (224 at the global size limit of 32), across loaded chunk boundaries in one SQLite transaction. A failed batch rolls back completely and cancels the triggering break.
  • Synthetic veins lock their complete shape once. The former moving 5×5×5 window was removed; all positions of the accepted shape (at most 32) are persisted on the first hit, so continued mining cannot extend the lock into another candidate.
  • Buried-ore encounters are materially more frequent. Candidate cells are now 8³ instead of 16³. All 11 bundled ores were measured and recalibrated with smaller veins and lower per-cell chances, raising encounter count without returning to large spheres. A deterministic 2×1 tunnel probe now guards distinct vein encounters and dry-spell distance instead of treating flat-layer hit density as player experience.
  • Oversized explosions are rejected in O(1). Events above 512 affected blocks are cancelled instead of trimming an arbitrarily large tail; accepted events still perform at most 512 ownership/exposure checks.
  • A failed lock can no longer expose an unauthenticated decoy. Synthetic and worldgen lock batches are all-or-nothing. SQLite failure is logged at SEVERE and propagates back to cancel the triggering break, explosion, burn, entity change, or piston event before the covering block disappears.
  • Existing databases upgrade safely. Vein algorithm version 3 invalidates only materialized_positions. Salt, epochs, dirty positions, eligible ores, suspended chunks, and all other state remain untouched.

Calibration

  • Critical-layer hits/10k: coal 21.289, iron 21.777, copper 22.852, gold 12.695, redstone 17.383, lapis 10.742, diamond 6.738, emerald 0.879, quartz 49.219, Nether gold 19.531, ancient debris 2.441.
  • Mean metres between distinct veins in an eight-surface 2×1 tunnel probe: coal 125.308, iron 125.069, copper 137.681, gold 255.004, redstone 163.840, lapis 220.660, diamond 434.013, emerald 1260.308, quartz 68.624, Nether gold 128.502, ancient debris Y9/Y15/Y60 1489.455 / 1057.032 / 1456.356.
  • Nether hits/10k at Y9 / Y15 / Y60: quartz 0 / 45.605 / 49.219, Nether gold 0 / 19.531 / 23.047, ancient debris 0.977 / 2.441 / 1.074. Ancient debris remains clearly rare without becoming functionally absent.
  • Current sampled vein maxima match the shipped bounds: coal/iron/redstone/nether gold 7, copper 8, gold 6, lapis/diamond 5, emerald 2, quartz 9, ancient debris 3. No same-ore layer component exceeded its configured maximum.
  • Fixed 64³ samples contain 1,060 ore blocks in the Overworld and 1,660 in the Nether (0.404% / 0.633% of sampled coordinates), below the test ceilings of 1,200 / 1,800.

Verification

  • ./gradlew test: 76 tests passed, including the v1.3.2 visible-ore failure reproduction, salt separation, fixed continuation/frontier limits, negative cross-chunk atomic rollback, algorithm-v2 migration, tunnel dry spells, connected components, priority overlap, Y boundaries, and Nether ratios.
  • L3: Paper 26.2 build 65 enabled Kyokalith 1.3.3 with 11/11 ores; /kyo stats and plugin version responded normally, shutdown was clean, and no test server process or port remained.
  • L4 focused regression: the final packaged JAR was exercised by Mineflayer 1.21.11 through official ViaVersion/ViaBackwards 5.11.0 on a localhost-only test server. It broke one visible iron entrance and followed newly exposed ore to a six-block vein within the shipped 3..7 bound. This proves the reported surface-only path through real BlockBreakEvent; broader multi-biome mining feel remains a deployment-test task.
  • Production deployment was not performed.

[1.3.2] - 2026-07-24

Changed

  • vein_size now means an exact block count (1–32). Each accepted veinId grows as a deterministic, face-connected voxel shape with a hard proof-friendly upper bound; the former size-to-radius sphere mapping is gone. Different sizes now change actual vein volume instead of being magnified or collapsed by integer radius conversion.
  • Candidate arbitration is whole-vein atomic. Touching same-ore candidates suppress the higher stable veinId, preventing adjacent cells from merging into a long belt. If different ore shapes overlap, the lower priority candidate is discarded in full; equal priority falls back to lower veinId. Every survivor therefore keeps its complete connected shape and exact target count instead of leaving 1–2 block fragments.
  • Y distributions can use y_weight_points. The optional sorted [y, weight] list is linearly interpolated; definitions without it keep the legacy triangular preferred_y fallback. The cell cache is now bounded at 20,000 entries.
  • YAML config schema v2. The bundled config now declares config_schema_version: 2. Upgrade detection reads only the file-owned value before Bukkit merges defaults, keeping YAML schema, DB schema, and vein-algorithm versions independent.
  • All 11 bundled ores were recalibrated from measurements. Current critical-layer coordinate hits/10k are coal 9.082, iron 8.105, copper 5.566, gold 2.539, redstone 3.418, lapis 4.688, diamond 1.563, emerald 0.293, quartz(y60) 18.945, nether gold(y15) 7.129, and ancient debris(y15) 0.781. Distinct encounters/10k in the same order are 2.734, 2.734, 1.660, 1.074, 1.563, 1.563, 0.879, 0.293, 7.520, 2.734, and 0.586.

Fixed

  • Finite veins and restored encounter spacing. The v1.3.0 baseline converted configured sizes into overlapping spheres and measured only hit-coordinate density, masking the combination of huge individual veins and long distances between encounters. Baseline volume samples found only 4 overworld veins (max 123) and 15 Nether veins (max 257), plus a reproducible 613-block legacy quartz chain. v1.3.2 samples found 54 overworld veins (max 9, P50 5, P95 9; nearest-vein P50 11.18, P95 19.90) and 75 Nether veins (max 14, P50 8, P95 13; nearest-vein P50 9, P95 14.765). The largest Nether mixed-ore connected component was 15; no single surviving veinId exceeded its configured exact size.
  • Already-visible ore beside rails and other non-occluding blocks no longer re-resolves. The old exposure test recognized only air/water/lava, so ore beside a rail could be visible to the player yet still be classified as buried; removing the rail then falsely triggered "first exposure" and could make that ore disappear. Exposure now uses Bukkit Material.isOccluding. Listeners snapshot each removed block's occlusion state before the event applies; Paper and ownership-verified Folia execution therefore make the same decision in the event tick.
  • 5×5×5 materialization locks cannot relay into another vein. A hit persists only positions that resolve to the trigger's exact accepted veinId; ordinary misses and neighboring candidates are not written. Work remains bounded to at most 124 extra checks per hit, without scanning chunks, force-loading neighbors, or changing unexposed blocks.
  • Explosion exposure work now has a hard event bound. EntityExplodeEvent and BlockExplodeEvent block lists are capped at 512 during HIGHEST, before the MONITOR materialization pass snapshots them. Excess entries are removed from the event list—so those blocks remain in the world—and a warning records the requested and retained counts. Eligible-ore cleanup also runs at MONITOR against the capped final list, so retained blocks do not lose their token state.
  • Folia region ownership is now enforced rather than assumed. Before any exposure handler reads a block plus its neighboring chunk radius, it verifies Bukkit.isOwnedByCurrentRegion. Unsafe single-block/piston events are cancelled; foreign explosion entries are removed from the event list and remain in the world. Paper/Spigot keep their normal single-thread behavior.
  • Priority arbitration now considers only ores that support the queried base material. A high-priority deepslate-only definition can no longer suppress a valid stone ore (or vice versa) and leave an empty hole in custom API configurations.
  • Existing databases invalidate only stale derived locks. On first startup, algorithm metadata v2 clears materialized_positions once and preserves salt, epochs, dirty positions, eligible placed ores, suspended chunks, and all other state.
  • Old configs no longer inherit incompatible v2 Y curves. The first runServer attempt with a real v1 config reproduced a fail-fast disable: Bukkit copyDefaults had inserted new y_weight_points while retaining old y_min/y_max, creating endpoint mismatches. v1 startup now clears only inherited curves, warns, saves schema 2, and falls back to each existing preferred_y triangle. The complete v2 config shipped in the patch is still required to enable the measured calibration curves.
  • Nether bands remain useful without flattening rarity. Quartz / Nether gold / ancient debris hits per 10k are y9 0 / 0 / 0.684, y15 18.652 / 7.129 / 0.781, and y60 18.945 / 6.055 / 0.293. Ancient debris remains clearly rarer than common ores without returning to near-zero.

Verification

  • L1: deterministic geometry, distribution, connected-component, spacing, overlap, materialization-lock, non-occluding exposure snapshot, 512-block explosion cap, negative-coordinate/boundary, and database-migration tests produced the evidence above.
  • L3 startup: after the schema-aware merge fix, runServer enabled Kyokalith 1.3.2 with both a legacy config (11/11 ores using triangular fallback) and the complete shipped v2 config (/kyo stats 11/11), then stopped normally. The final log contained no ERROR/SEVERE/Exception and ports 25565/25575 were released. L4 player-visible mining behavior remains unverified; no production deployment was performed.

[1.3.0] - 2026-07-24

Added

  • ores.<oreType>.priority config field (original 1.3.0 behavior, superseded). This release introduced operational cross-ore ordering and exposed the winning priority in /kyo inspect. Its coordinate-level overlap behavior was replaced by v1.3.2's whole-candidate atomic arbitration.
  • Persisted vein locking (materialized_positions table; original 1.3.0 behavior, superseded). This release introduced bounded 5×5×5 derived locks without writing unexposed blocks. v1.3.2 narrows those locks to the trigger's exact veinId and performs the one-time algorithm-v2 invalidation described above.

Fixed

  • Historical vein-radius change (superseded by v1.3.2). This release still used sphere geometry; v1.3.2 replaces that model with exact, bounded connected shapes and should be used for current behavior and tuning guidance.
  • ancient_debris was functionally absent in the y8-22 band it's supposed to live in. cell_chance was 0.006 (the lowest of any ore, ~8x lower than the next-rarest) and vein_size_max was 2 — Monte Carlo sampling (NetherOreDensityMonteCarloTest, method: resolve every coordinate in a fixed-Y grid, count hits per 10,000 samples) measured this at 0.14/10k at y8, 0.056/10k at y15, 0.0/10k at y22 — i.e. not just rare, essentially zero. That's the real root cause of "can't find ancient debris near y15" reports (nether_quartz/nether_gold's y_min: 10 is correct vanilla behavior and was not touched — Monte Carlo showed no anomaly there once aggregated over a Y-band, see the test). cell_chance 0.006 → 0.05 (~8x) and vein_size_max 2 → 3 (matching vanilla's real per-vein block count of 3 for both of its overlapping distributions) measures 0.81/10k at y15 — about 14x the old value, and still only ~9% of nether_quartz's own measured peak density (9.17/10k at its preferred Y of 60) — clearly rarer than a common ore, no longer indistinguishable from zero. y_min/y_max/preferred_y (8/119/15) were left as-is; they already matched vanilla's dual-distribution shape.

[1.2.1] - 2026-07-23

Fixed

  • Ore could flicker into view and back out during normal mining. Branch/"fishbone"-style miners reported real ore blocks visibly appearing then disappearing in front of them, or a promising-looking vein resolving to only a couple of real ore blocks. Root cause: first-exposure resolution required the neighbor's live block state to already show the removal (already air/water/lava), so every listener deferred a full tick via Schedulers.atRegion and let vanilla's own block removal land first. But a buried decoy is genuine world data already sitting in every player's loaded-chunk cache — that's the whole point of the anti-X-Ray model. The instant the covering block's removal reaches the client, face culling renders whatever the decoy actually is; Kyokalith's correction (real ore, or a revert to stone) only lands a tick later, so the player briefly sees the decoy's true, unresolved appearance before it flips. MaterializationService.isNewlyExposed (now a pure, unit-tested function) treats a neighbor's membership in the triggering event's own removed set as sufficient evidence it is about to go transparent, so resolution no longer needs to wait for the removal to actually apply. MaterializationListener's block-disappearance handlers moved to EventPriority.MONITOR (so no other plugin can still cancel the event out from under us) and now call Schedulers.atRegionNow instead of Schedulers.atRegion — running inline, in the same tick as the triggering event, whenever the current thread already owns the block's region (the normal case: a player breaking a block in front of themselves). Multi-block events that happen to straddle a Folia region boundary still fall back to the next tick, same as before. No change to the decoy model, the vein function, or eligibility — this only closes the reveal-then-correct timing gap.

This mod has no additional files