Compatibility
Minecraft: Java Edition
1.20.1–1.20.6
Platforms
Supported environments
Client and server
Creators
Details
Licensed MIT
Published 2 months ago
Changelog
v1.2.0
New Features
Route Chunk Preloader
- New chunk preloading system along the railway route using Create's track graph
- Uses
getChunkFuture(FULL)to load chunks into memory without force-loading (no entity-ticking) - Dedicated
COT-RouteChunkPreloaderthread to avoid blocking the server tick - ~256 block lookahead, maximum of 24 chunks per train
Directional Chunk Loading
ChunkMapMixinfilters new chunks sent to the client when the player is riding a train- Lateral chunks outside the directional area are not loaded (front/back have priority)
DirectionalChunkShapertracks players on trains and calculates direction with EMA smoothing- Compatible with Distant Horizons — DH uses its own LOD system independently
Player Proximity Buffer
updatePlayerProximityBuffer()preloads chunks in the buffer zone (view distance + 1~3 chunks)- Carriage entities are created and positioned BEFORE the player can see them
- Result: trains appear fully positioned with no ghost/stutter
Position Snap (Client)
CarriageEntityClientMixinforcesxo=x, yo=y, zo=zfor the first 5 ticks after spawn- Prevents visual interpolation/sliding when carriage entities are created
F3 Debug Overlay
- COT information on the F3 screen: memory, threads (pool/active/queued), TPS/MSPT/Peak, state/factor, FPS, chunks forced/route-cached
- JVM thread count cached every ~1s to prevent flickering
- Can be disabled via
DEBUG_OVERLAY_ENABLEDconfig
Safe Train Tick Protection
SafeTrainTickMixinwrapstrain.earlyTick()in a try-catch insideGlobalRailwayManager.tickTrains()- If an external mod (e.g. RailX) crashes during a train's tick, the train skips the tick instead of crashing the server
- Logging limited to 3 warnings per train to avoid spam
- Prevents crash loops that block worlds from loading
Improvements
Chunk Load Manager
- Directional lookahead based on real train movement (deltaMovement + fallback to position delta)
- Adaptive lookahead capped at 6 chunks (entity-ticking is CPU-expensive)
- Side chunks (for curves) only for the 3 nearest chunks
getCarriagePosition()usesDimensionalCarriageEntity.positionAnchoras fallback for carriages without entities- Anti-thrashing with 12-chunk recent history
Render Optimization
- LOD-based render skipping by distance (>256 blocks = culling)
- Flywheel update skipping for distant trains (LOD > MEDIUM)
- Per-train visibility tracking for LOD decisions
getClientFPS()cached every 30 frames
LOD System
- Buffer zone: trains approaching the player forced to LOD FULL
- Temporal hysteresis (500ms minimum between LOD changes) to prevent flip-flop
- Player position caching for thread-safe calculations
- Distances adjustable by the Performance Monitor
Bug Fixes
Invisible Trains (Critical)
- Cause: Fade-out system marked all distant trains as "departing" on world load →
getDepartureScale()returned -1 after 12 frames → renderer permanently skipped them - Fix: Fade-out system completely removed.
getDepartureScale()always returns 1.0f,startFadeOut()is a no-op,isFadingOut()returns false
Inflated Chunk Tracking (Critical)
- Cause:
trainChunks.put(trainId, needed)stored ALL "needed" chunks even when the global cap (30) blocked force-loading →getLoadedChunkCount()inflated (reached 196) → cap blocked everything → trains without entity-ticking → movement stuttering - Fix:
trainChunksnow only stores chunks actually forced on the server. Cap calculation uses exact count:otherTrainsCount + actuallyForced.size()
OOM from Forced Chunk Leak
- Cause:
RouteChunkPreloaderusedsetChunkForced()instead of just loading into memory → forced chunks accumulated without limit - Fix: Replaced with
getChunkFuture(FULL)— loads chunks into memory without force-loading
RejectedExecutionException
- Added
isShutdown()guards inAsyncTaskManagerbefore submitting tasks - Prevents crash during server shutdown
World Stuck at 100%
- Cause: Global startup delay blocked all Create systems
- Fix: Delay now applies only to chunk operations, not to the general tick
Configuration
New options in create_optimized_trains-common.toml:
DEBUG_OVERLAY_ENABLED— Show F3 overlay (default: true)DIRECTIONAL_CHUNK_LOADING— Directional chunk loading (default: true)DIRECTIONAL_FORWARD_CHUNKS— Forward chunks (default: 12)DIRECTIONAL_BACKWARD_CHUNKS— Backward chunks (default: 4)DIRECTIONAL_SIDE_CHUNKS— Side chunks (default: 5)CHUNK_LOOKAHEAD— Base lookahead chunks (default: 3)
Mixins
Server (7)
TrainMixin— carriageWaitingForChunks bypass + collision throttlingSafeTrainTickMixin— try-catch protection on earlyTickCarriageMixin— 60-tick grace period for chunksCarriageEntityMixin— isActiveChunk always trueDimensionalCarriageEntityMixin— isActiveChunk always trueContraptionCollisionMixin— Collision throttlingChunkMapMixin— Directional chunk filtering
Client (7)
CarriageRendererMixin— Render skipping by LOD/distanceCarriageContraptionVisualMixin— Flywheel update skipping by LODCarriageEntityClientMixin— Position snap for first 5 ticksContraptionEntityRendererMixin— Render optimizationContraptionVisualMaterialMixin— Material optimizationLevelRendererFlushMixin— Flush optimizationOitDepthMixin— Depth sorting fix
Dependencies
- Minecraft 1.20.1
- Forge 47.4.16+
- Create Mod 6.0.8+
- Flywheel 1.0.5 (JiJ'd inside Create)
- Mixin 0.8.5
Files
create-optimized-trains-1.2.0.jar(700.09 KiB) Primary
Metadata
Release channel
BetaVersion number
1.2.0Loaders
Forge
Game versions
1.20.1–1.20.6Environment
Client and server, required on both


