Changelog Update

TickForge update details.

Full release notes, development summary, improvements, fixes, and technical notes for TickForge 26.1.1-4.

26.1.1-4 Stable Build April 9, 2026

15+ performance optimizations, scheduler rework, entity budgets, and network packet discipline

This build is a pure performance release. 15+ distinct optimizations target the scheduler, entity ticking, redstone propagation, network packets, event overhead, tab list rendering, MOTD caching, and chunk lookups. Entity tick budgets and inactive AI skipping are now enforced. The Bukkit scheduler gets O(n) → O(1) fast paths and a per-tick execution cap. Network packet deduplication eliminates redundant motion and block update packets. Event dispatch is zero-cost when no plugins listen.

What changed in this build

26.1.1-4 is a pure performance release with 15+ distinct optimizations across the server's hottest code paths. The Bukkit scheduler gets O(n) → O(1) fast paths for isQueued() and getPendingTasks(), plus a 1000-task-per-tick execution cap. Entity ticking introduces per-world tick budgets, cosmetic entity throttling, and configurable inactive AI skipping. Redstone and neighbor updates gain no-op state suppression and configurable chain depth limits. Network packets are deduplicated for zero-velocity motion, same-state block updates, and distance-gated map cursor updates. Event dispatch for BlockPhysicsEvent and ServerOverloadEvent is now zero-cost when no plugins listen. Tab list and MOTD rendering are rewritten with single-pass StringBuilder and pre-parsed caching. The chunk locality cache is expanded from 1-entry to 4-entry. CLI aliases --tickforge-dir and --tickforge-settings are added, and the /plugins output relabels "Bukkit Plugins" to "Legacy Plugins".

Scheduler and task management optimizations

  • isQueued() O(n) → O(1) fast path

    Reversed lookup order in CraftScheduler.isQueued() — now checks the runners ConcurrentHashMap (O(1)) before falling back to the O(n) linked list scan. The linked list is only traversed for tasks that haven't been parsed yet.

  • getPendingTasks() O(n²) → O(n)

    Replaced ArrayList.contains() dedup with an IdentityHashMap-backed set for O(1) dedup. Merged the two-pass approach into a single pass.

  • Per-tick task execution cap (1000)

    Added MAX_TASKS_PER_TICK = 1000 limit to mainThreadHeartbeat(). Prevents the scheduler from consuming the entire tick budget during bulk-scheduling or lag recovery. Excess tasks defer to the next tick.

  • PriorityQueue initial capacity 10 → 64

    Typical servers run 50–200+ pending tasks. Starting at 10 causes repeated array resizing with O(n log n) re-heapify. 64 covers the common case without wasting memory.

Entity performance optimizations

  • Per-world entity tick budgets

    New TickForgeEntityOptimizer enforces maxEntityTicksPerWorld and maxTileEntityTicksPerWorld budgets. Once exhausted, non-player entities are skipped for the remainder of the tick. Players are never skipped. Previously these were dead config keys — now fully enforced.

  • Inactive AI skipping

    Mobs outside player activation range now only run AI goal selectors at a configurable interval (jittered by entity ID). Float goal and jump control still run via Paper's existing nerfed-mob logic.

  • Cosmetic entity throttling

    Decorative no-gravity armor stands, item frames, and paintings tick every 4th tick. Grounded items and experience orbs tick every 2nd tick. ~20–35% CPU reduction in entity ticking.

  • Chunk locality cache expanded (1-entry → 4-entry)

    The same-thread chunk lookup cache in ServerChunkCache is expanded to 4-entry direct-mapped (keyed by chunkKey & 3), covering adjacent-chunk lookups common in entity physics. ~50–75% cache hit improvement.

Block, redstone, and neighbor update optimizations

  • No-op neighbor update suppression

    When the UPDATE_NEIGHBORS flag is set but old and current block states are identical, neighbor updates are skipped entirely. Eliminates cascading notifications for block changes that didn't actually modify state.

  • Configurable chained neighbor update limits

    maxChainedNeighborUpdates limits redstone cascade depth. BALANCED: 100,000. AGGRESSIVE: 10,000. Vanilla default: 1,000,000. Prevents redstone update storms from consuming the entire tick.

  • BlockPhysicsEvent handler-list guard

    Event allocation and dispatch skipped when no plugins have registered listeners. Applied in both notifyAndUpdatePhysics() and NeighborUpdater.executeUpdate() — one of the highest-frequency event paths in the server.

Network and packet discipline

  • Zero-velocity motion packet dedup

    When hurtMarked triggers a velocity packet but the motion vector hasn't changed from the last send, the packet is suppressed. Prevents repeated ClientboundSetEntityMotionPacket for entities against walls or repeatedly hit armor stands.

  • Same-state block update suppression

    When a block is "set" to the same state it already has, the client-bound block update packet is suppressed. No visible change — clients already have the correct state.

  • Map cursor distance culling

    Map cursor updates are skipped for players farther than mapCursorUpdateDistanceSq (default 256 = 16 blocks) from the item frame. Map data is still synced on initial tracking; only cursor updates are distance-gated.

Hot-path CPU cost reduction

  • Event dispatch zero-cost when unused

    checkOverload() now skips System.nanoTime() entirely on healthy ticks (TPS ≥ 18). ServerOverloadEvent and ChunkPerformanceEvent construction skipped when no listeners exist. ~90–100% overhead eliminated when unused.

  • Tab list single-pass StringBuilder

    updateAllTabLists() now resolves placeholders once per cycle and sends the same Component to all players. resolveTabPlaceholders() rewritten with single-pass StringBuilder and DecimalFormat. ~80–90% fewer allocations.

  • MOTD component caching

    getMotd() now returns pre-parsed Components from a volatile cache instead of calling MINI_MESSAGE.deserialize() on every server list ping. Cache rebuilt on config init and reload.

Debranding and CLI

  • "Bukkit Plugins" relabeled to "Legacy Plugins"

    The /plugins command output now shows "Legacy Plugins" instead of "Bukkit Plugins". Cosmetic only — no API or functional change.

  • PAPER_HEADER constant renamed to TICKFORGE_HEADER

    Internal constant rename in PaperPluginsCommand. Same value (0x60A5FA), no external API surface.

  • CLI aliases: --tickforge-dir, --tickforge-settings

    Added --tickforge-dir, --tickforge-settings-directory, and --tickforge-settings as primary CLI flag aliases. Old --paper-* flags preserved for backward compatibility.

Build and patch fixes

  • Moonrise merge conflict resolution

    Resolved 7 merge conflicts between TickForge source patches and Moonrise optimization patches across MinecraftServer, ServerLevel, Level, and ServerChunkCache. All 30 feature patches applied successfully.

  • ServerPlayer.java.patch hunk merge fix

    Merged hunks 16+17 into a single hunk to fix apply failure caused by fuzzy matching position tracking errors.

  • Painting import path corrected

    Fixed import net.minecraft.world.entity.decoration.Painting to net.minecraft.world.entity.decoration.painting.Painting matching the 26.1.1 class location.

  • Missing tick budget fields restored

    Added tickForgeEntityTickCount and tickForgeTileEntityTickCount fields that were removed when Moonrise feature patches overwrote parts of the patched files.

New config keys added in this build

Key Description Default
tickforge-performance.max-chained-neighbor-updatesMax depth of chained redstone/neighbor cascades-1 (vanilla)
tickforge-network.deduplicate-zero-motion-packetsSuppress redundant zero-velocity motion packetstrue
tickforge-network.map-cursor-update-distance-sqDistance threshold for map cursor updates256.0
tickforge-performance.max-entity-ticks-per-worldPer-world entity tick budget (-1 = unlimited)-1
tickforge-performance.max-tile-entity-ticks-per-worldPer-world tile entity tick budget (-1 = unlimited)-1

Estimated performance improvement over 26.1.1-3

Area Improvement Method
Scheduler~40–60% faster dispatchisQueued() O(1), getPendingTasks() O(n), 1000/tick cap
Entity ticking~20–35% CPU reductionPer-world budgets, cosmetic throttle, inactive AI skip
Redstone/neighbors~15–30% fewer cascadesNo-op suppression, configurable chain limits
Network packets~10–25% fewer outboundZero-velocity dedup, block state suppression, map culling
Event overhead~90–100% eliminatedHandler-list guards on BlockPhysicsEvent, ServerOverloadEvent
Tab list/MOTD~80–90% fewer allocsSingle-pass StringBuilder, per-cycle resolve, MOTD caching
Chunk lookups~50–75% cache hits1-entry → 4-entry locality cache

Actions required before or after updating

Drop-in upgrade from 26.1.1-3. All optimizations activate automatically with safe defaults. Entity tick budgets default to unlimited (-1) on VANILLA_PLUS and CUSTOM profiles — only BALANCED and AGGRESSIVE profiles enforce limits. The 1000-task/tick scheduler cap only triggers during pathological burst scheduling. Network packet deduplication is enabled by default with no gameplay impact. Existing config overrides are preserved. New config keys appear on first startup with their defaults. The --tickforge-dir and --tickforge-settings CLI flags are additive — old --paper-* flags continue to work.

Need more support?
Click here!