promotional bannermobile promotional banner

Create : Tick Control

Create Tick Control optimisation smart block entities ticks optimise create server and client
Back to Files

createtickcontroller-1.21.1-1.2.0.jar

File namecreatetickcontroller-1.21.1-1.2.0.jar
Uploader
arginou57arginou57
Uploaded
Aug 16, 2026
Downloads
19
Size
253.1 KB
Mod Loaders
NeoForge
File ID
8665904
Type
R
Release
Supported game versions
  • 1.21.1

Curse Maven Snippet

NeoForge

implementation "curse.maven:create-tick-control-1418208:8665904"

Learn more aboutΒ Curse Maven

What's new

# Create Tick Controller 1.2.0

The biggest performance update so far, on **both sides of the wire**: a client-side system that recovers FPS in large Create bases, and a family of server-side exponential backoffs that stop jammed logistics blocks from grinding full scans every tick.

## πŸ–₯️ Client-side distance tick reduction β€” the FPS update

Every Create block entity also ticks **on the client** every game tick: animation lerps, belt item simulation, effects. In a large base that's thousands of client ticks per frame budget β€” the F3 profiler shows `tick` eating 70%+ of the frame while `gameRenderer` starves. That's where your FPS went.

Create block entities now tick at **full rate near the camera and reduced rate with distance**:

| Distance from camera | Tick rate |
|---|---|
| < 32 blocks | full rate β€” everything up close stays flawless |
| 32–64 blocks | every 2nd tick |
| beyond 64 | every 4th tick (configurable up to 16) |

Why this is nearly invisible:

- **Kinetic rotation (shafts, wheels, fans, gearboxes) is computed at render time, not tick time β€” it stays perfectly smooth at any distance, even throttled.**
- Belt items and flaps beyond 32 blocks advance slower between server syncs β€” imperceptible at that range, and any belt event re-snaps them.
- Ambient machine sounds are driven by close-range ticks: with `fullRateDistance β‰₯ 32` they are untouched.
- Ponder scenes and contraptions (trains, elevators β€” they're entities) are exempt.
- Purely visual and **local to each client** β€” server logic, item transport and other players never see a difference.

A per-position phase offset spreads the remaining work evenly across ticks, so the saving never bunches into a periodic stutter.

### In-game controls

**`/ctcclient`** β€” client command, works on any server (the setting is local), persists to `createtickcontroller-client.toml`:

| Preset | Full rate | Half rate | Far divisor | For |
|---|---|---|---|---|
| `/ctcclient light` | 48 | 96 | Γ·2 | barely-visible safety margin |
| `/ctcclient default` | 32 | 64 | Γ·4 | the shipped defaults |
| `/ctcclient aggressive` | 24 | 48 | Γ·8 | big bases |
| `/ctcclient extreme` | 4 | 16 | Γ·16 | FPS above all β€” only your immediate surroundings tick at full rate; expect visibly slower flaps and belt items past arm's reach |

Plus `on` / `off`, `set <fullRate> <reducedRate> <farDivisor>` for fine tuning, and bare `/ctcclient` to show the current state.

There is also a **config screen** now: Mods list β†’ Create Tick Controller β†’ Config (NeoForge's built-in UI, no extra dependency).

**Sodium users** get the settings right inside Sodium's Video Settings menu: a "Tick Reduction" page with a toggle and three sliders, each with an explanatory tooltip (English + French). Works with both Sodium lines on 1.21.1 β€” 0.8+ via the official Config API, 0.6 via an optional hook β€” with no extra dependency; without Sodium the page simply doesn't exist and the other controls remain.

### What FPS gain to expect (estimates + the math)

These are **reasoned estimates, not benchmarks** β€” replace them with your own A/B numbers before quoting them. The model: block entities are spread over the loaded area, which grows with the *square* of distance, so the overwhelming majority of ticking machinery sits in the outer bands. At 12 chunks render distance (~192 blocks), the share of block entities inside a 32-block radius is only ~3% of the loaded area; inside 4 blocks it is statistically zero.

Cost of the client BE tick pass remaining per preset (uniform spread assumption, 192-block loaded radius):

| Preset | Bands | BE tick cost remaining | BE tick cost removed |
|---|---|---|---|
| `default` | 32 / 64 / Γ·4 | ~29% | **~71%** |
| `aggressive` | 24 / 48 / Γ·8 | ~15% | **~85%** |
| `extreme` | 4 / 16 / Γ·16 | ~7% | **~93%** |

Translating to FPS: with the profile described above (client `tick` β‰ˆ 75% of the frame) and `blockEntities` making up 80–90% of that slice (typical for belt/funnel-heavy Create bases), block entity ticking is ~60–68% of total frame time. Removing it per the table gives an estimated frame-time reduction of:

| Preset | Estimated FPS multiplier (BE = 60% of frame) | (BE = 68% of frame) |
|---|---|---|
| `default` | ~Γ—1.7 | ~Γ—1.9 |
| `aggressive` | ~Γ—2.0 | ~Γ—2.4 |
| `extreme` | ~Γ—2.3 | ~Γ—2.7 |

Example: a base running at 30 FPS with that profile lands around **50–55 FPS on `default`** and **70–80 FPS on `extreme`**. Machinery clustered close to the player lowers these numbers; machinery spread wide raises them.

Caveats that change the outcome:

- The estimates assume `blockEntities` dominates your `tick` slice β€” verify in the F3 profiler pie: `tick` β†’ `level` β†’ `blockEntities`. If `entities` (many active contraptions, ground items) or `particles` dominates instead, this lever won't move it β€” report what the profiler shows and we'll target that next.
- Only Create block entities are throttled; vanilla and other-mod BE ticks are untouched and bound the ceiling.
- Quick A/B test in your base: `/ctcclient off`, note FPS β†’ `/ctcclient extreme`, compare. Ten seconds, no restart β€” that number is the real one.

## πŸ” Exponential backoff for jammed logistics (server-side)

Generalizes the Sophisticated Storage hopper backoff from 1.1.1 to every remaining every-tick retry loop we found. Shared principle: **each attempt that moves nothing doubles the wait** (2, 4, 8… ticks, capped); the first success or relevant change resets to full speed instantly. Working blocks are never slowed β€” only ones stuck in a retry loop. New config section `backoff`, everything on by default.

### Create belts β€” `backoff.belts` (cap 40 ticks = 2s)

A backed-up belt (items blocked by a full container or the item in front) still ran its **complete per-item transport loop every tick**: position bookkeeping, one block-state lookup per item for funnel checks, an end-of-belt insertion attempt β€” with no early-out in Create. A 20-item jammed belt did all of it, 20 times a second, forever. Now: when a tick changes nothing, the transport pass skips with doubling backoff. Wakes instantly on item insertion, machine access (press/deployer/fan), or any speed change; a freed container is polled within 2s. Kinetics, entity transport and rendering never skipped.

### Create funnels β€” `backoff.funnels` (cap 40 ticks = 2s)

Create only starts the extraction cooldown on a *successful* transfer β€” a funnel facing a jammed belt re-ran its whole activation path (state reads, behaviour lookups, belt occupancy scans) every tick. Failed attempts now write a doubling delay into the funnel's own cooldown. Passive directions (items flowing *into* a funnel) are untouched; redstone still resets instantly.

### Create factory gauge panels β€” `backoff.factoryPanels` (cap 40 ticks = 2s)

Every active gauge polls the logistics network **every tick** (stock summary, promise queue, link state) even while nothing can happen: satisfied, promise-covered, redstone-stopped, or waiting on unloaded chunks. A wall of gauges multiplies that by hundreds. Idle panels now back off; redstone edges and player edits wake them instantly, stock changes are seen within 2s. Two hard guarantees: panels counting down to a request are **never** slowed (request cadence stays exact), and restocker promise ages keep ticking so promise expiry stays exact.

### Vanilla hoppers β€” `backoff.vanillaHoppers` (cap 20 ticks = 1s)

Vanilla only sets its 8-tick cooldown after a *success* β€” a blocked hopper repeats its full transfer scan (every hopper slot Γ— every container slot + an item-entity sweep) **every single tick, forever**. This is the most classic hidden server cost in modded and vanilla alike. Failed attempts now back off; hopper-to-hopper transfers still wake the receiver instantly (the backoff is invisible to vanilla's `isOnCustomCooldown` wake check). Redstone-sensitive hopper contraptions (hopper clocks) can turn this off.

### What MSPT gain to expect

Server-side, so it buys **TPS headroom**, not FPS directly. The win scales with how much of your factory is idle-but-polling at any moment β€” in mature bases that's most of it (full buffer chests, satisfied gauges, belts waiting on packagers). Blocks in backoff cost near zero instead of their full scan; a base with hundreds of jammed belts/funnels/hoppers can shed several ms/tick. Measure with the dashboard profiler before/after: the belt/funnel/hopper types should drop toward the bottom of the ranking.

## Upgrade notes

- Drop-in replacement for 1.1.x β€” no migration; the new `backoff` (server) and `clientTicks` (client) sections generate with safe defaults. The client half only activates for players who install the mod client-side.
- All mixin targets verified against Create 6.0.8 bytecode and vanilla 1.21.1 mojmap. **Not yet field-tested** β€” validate on a dev instance first: unjam a full belt (resumes ≀ 2s), pulse a gauge with redstone (instant), run `/ctcclient` A/B in your biggest base.
- If a specific machine misbehaves, each backoff has its own toggle in `backoff.*` β€” disable just that one and report it.