createtickcontroller-1.21.1-1.2.0.jar
Curse Maven Snippet
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.
This mod has no additional files

