Tags
Creators
Details
1.1.6+26.2
Compatibility
Required content
Changes
1. src/main/java/com/mahidx7/forkclient/client/modules/EntityCullingModule.java
- Static utility class (follows AntiKnockbackModule pattern)
- Async thread pool (Executors.newFixedThreadPool, daemon threads at NORM_PRIORITY - 1)
- Double-buffered results ā writeBuffer (ConcurrentHashMap) receives worker results; readBuffer (volatile) is read by the render thread after an atomic swap
- DDA ray-step path-tracing ā walks a ray from camera to entity center through the block grid, stepping one block at a time via the axis-crossing DDA algorithm
- Occlusion check uses BlockState.isSolidRender() ā the exact predicate MC uses internally for face-culling during chunk meshing (passes for stone/dirt/deepslate, fails for glass/water/leaves/slabs)
- Entities too close (< 1.5 blocks) or too far (> 128 blocks) are never culled (avoids visual artefacts)
- Position-keyed via spatial hash (x73856093 ^ y19349669 ^ z*83492791) for frame-to-frame matching
2. src/main/java/com/mahidx7/forkclient/mixin/LevelRendererMixin.java
- @Inject at HEAD of submitEntities ā calls EntityCullingModule.update() with the entity render state list and camera position
- @Redirect on EntityRenderDispatcher.submit() ā intercepts each entity dispatch and skips rendering if shouldSkip(state) returns true Modified files:
3. ForkClientController.java:332 ā registered "entity_culling" module under ModuleCategory.VISUAL
4. fork-client.mixins.json ā added "LevelRendererMixin" to the client mixin list Architecture
Frame N:
submitEntities() called
āā @Inject HEAD ā EntityCullingModule.update()
āā Swap double buffers (Frame N-1 writes ā Frame N reads)
āā Populate skipPositions from readBuffer (cached results)
āā Submit async trace tasks for cold entries ā writeBuffer.`
āā for each EntityRenderState:
āā @Redirect on dispatcher.submit()
āā if shouldSkip(state) ā return (skip rendering)
āā else ā dispatcher.submit() (normal path).
One frame of latency (standard for async entity culling ā used by Sodium, Etho's EntityCulling, etc.) ensures the render thread never stalls on ray-tracing.
Projects on Modrinth are automatically available through a Maven repository for use with JVM build tools such as Gradle. To learn more about the Modrinth Maven API, click here.
Note: When available, you should use the creator's maven repo instead as it will have transitive dependency information that the Modrinth Maven API does not. You may also end up with duplicate dependencies if you use a mix of Modrinth and non-Modrinth Maven repositories for your dependencies, because the group identifier will be different when served through the Modrinth Maven API.
Maven coordinates:
Version ID:
build.gradle:
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
// Standard Gradle dependency
dependencies {
implementation "maven.modrinth:2hEMWpQc:w9P7TARb"
}
// Legacy Loom dependency
dependencies {
modImplementation "maven.modrinth:2hEMWpQc:w9P7TARb"
}

