COWMODSКаталог модов
Statestream

ВЕРСИИ (3)

release

Statestream 1.0.1

1.0.1
24 мая 2026 г.940Minecraft: 26.1, 26.1.1, 26.1.2forge, neoforge
Скачать
release

Statestream 1.0.1

1.0.1
24 мая 2026 г.930Minecraft: 26.1, 26.1.1, 26.1.2fabric, forge, quilt
Скачать
Что нового
# 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
release

1.0.0

1.0.0
14 мая 2026 г.125Minecraft: 26.1, 26.1.1, 26.1.2fabric, forge
Скачать