▶️ ЗАБЕРИ СВОИ 8 ПОДАРКОВ 🎁 ПРИ СОЗДАНИИ СВОЕГО МАЙНКРАФТ СЕРВЕРА
Моды/Statestream
Statestream

Statestream

Radical performance optimization by reworking BlockState lookups and neighbor block updates.

Оцените первым
354
8
Все версииStatestream 1.0.1

Statestream 1.0.1

Release24.05.2026

Список изменений

StateStream Changelog

1.0.1 — Multi-loader support, critical fixes, major performance pass

Loader support

  • NEW: Native NeoForge build (statestream-neoforge-1.0.1.jar) targeting NeoForge 26.1.2.65-beta.
  • NEW: Native Quilt support via quilt.mod.json (also runs under Quilt's Fabric compatibility layer).
  • Refactored project into a loader-agnostic core (com.statestream.*) with separate entrypoints per loader (StateStreamFabric, StateStreamNeoForge).
  • Three distinct jars now shipped: Fabric, Quilt, NeoForge.

Critical bug fixes

  • Fixed silent data corruption when Y > 255. The previous position encoding masked Y to 8 bits, which collided for any block above Y=255 (Overworld extends to Y=320). The registry is now split per-section using section-local Y (4 bits) — collisions are mathematically impossible. New test allEncodingsUniqueWithinSection verifies every (x, z, ly) tuple produces a unique encoding.
  • Fixed registry corruption on every block placement and break. onBlockChanged was always receiving null for the old BlockState, which caused:
    • Duplicate entries when replacing a tickable block with another tickable block
    • Phantom entries (never removed) when a tickable block was destroyed
    • Tick loop wasting cycles on positions that no longer held tickable blocks
    • Old state is now captured at HEAD via a ThreadLocal and consumed at RETURN.
  • Added the /statestream enable <module> and /statestream disable <module> commands that the Modrinth description promised but didn't actually exist. Includes tab-completion for module names.

New feature: per-section tickable index with bitmap skip

The biggest performance win in this release. Each loaded chunk now keeps:

  • One sorted short[] per section containing only tickable positions
  • A 64-bit nonEmptyMask where bit s is set iff section s has at least one tickable block
  • The total tickable count for stats

The random-tick loop walks the mask using Long.numberOfTrailingZeros + mask & (mask-1) — empty sections are skipped at the cost of a single CPU instruction. On a typical Overworld chunk with tickables in only 3 of 24 sections, this is roughly an 8× reduction in section iterations per tick.

Probability parity with vanilla is preserved exactly: each section still rolls randomTickSpeed picks of nextInt(4096) and a tickable block still has P=1/4096 per roll.

Performance fixes

  • AtomicLong cache counters replaced with LongAdder — eliminates LOCK CMPXCHG contention on the per-call hot path.
  • Block state IDs are now cached on the BlockState itself via a @Unique mixin field on BlockBehaviour$BlockStateBase. First read pays a Reference2IntOpenHashMap.getInt(); every subsequent read is a single field load. Without this, the cache was doing a hashmap lookup to save a field lookup — a net loss.
  • onBlockChanged no longer allocates a HashSet per mutation. It now does CAS-based sorted-array binary insertion/removal. Lock-free, single allocation for the new array only.
  • onChunkLoad iterates LevelChunkSection arrays directly instead of calling chunk.getBlockState() ~98 000 times via BlockPos.betweenClosed. Empty sections are skipped at O(1).
  • UpdateCuller.shouldSuppress now has an O(1) empty-set early exit and an O(1) Block reference check (couldSuppressSource) that skips Identifier allocation entirely when the source block isn't involved in any pair. Internal storage switched from Set<String> to Map<Identifier, Set<Identifier>> — no more toString() + concatenation per call.
  • Tick loop now uses a single reusable BlockPos.MutableBlockPos instead of allocating one BlockPos per ticked block per tick.
  • Cache verification moved from per-call to one-shot at populate(). The hot path no longer pays for verification overhead.
  • Long2ObjectOpenHashMap candidacy preserved via ConcurrentHashMap<Long, ChunkEntry> — Long boxes are short-lived and escape-analysis-friendly.

Code quality

  • JSON parsing in UpdateCuller now uses Gson (with the hand-rolled string parser kept as a fallback for hostile input).
  • Config paths resolved via FabricLoader.getConfigDir() / FMLPaths.CONFIGDIR.get() on the respective loader, with a statestream.config.dir system property as the loader-agnostic bridge.
  • Mod version now read via Fabric's / NeoForge's ModContainer API instead of a hand-rolled JSON parser.
  • fabric.mod.json environment changed from "*" to "server" — the mod is no longer required on the client.

Tests

  • Updated for the new section-local encoding API (encodePos(x, z, ly) + matching decodeX/Z/LocalY).
  • New test allEncodingsUniqueWithinSection proving the Y-collision bug cannot recur.
  • New test nonEmptyMaskMatchesSectionContents covering the bitmap-walk semantics.
  • Counter assertions updated from AtomicLong.get() to LongAdder.sum().

Internal

  • New BlockStateIdHolder interface implemented on every BlockState via BlockStateBaseMixin.
  • New ReactiveTickRegistry.ChunkEntry immutable struct (per-section arrays + bitmap + count + minY).
  • New com.statestream.fabric package with the Fabric-specific entrypoint.
  • New neoforge/ Gradle subproject using net.neoforged.moddev 2.0.141.

1.0.0 — Initial release

  • JIT BlockState Inlining (BlockStateCache)
  • Update Culling (UpdateCuller)
  • Reactive Block Ticking (ReactiveTickRegistry)
  • Per-module fallback handler — any unexpected error disables the offending module and restores vanilla behavior
  • TOML config with independent toggles for each module
  • /statestream stats, status, reload, benchmark commands
  • Fabric loader for MC 26.1.2

Файлы

statestream-fabric-1.0.1.jar(41.12 KiB)
Основной
Скачать

Метаданные

Канал релиза

Release

Номер версии

1.0.1

Загрузчики

Fabric
Forge
Quilt

Версии игры

26.1–26.1.2

Загрузок

204

Дата публикации

24.05.2026

Загрузил

ID версии

Главная