
DashLoader (Unofficial Continuation)
Launch at the speed of light. Unofficial continuation of DashLoader by AlphaQ ported to newer Minecraft versions.
Оцените первым
55
0
Список изменений
Fixes
Cache writing
- Cache buffers are now allocated with
memAllocand freed deterministically.ByteBufferIO.createDirectis a plainallocateDirect, so the JDK zeroed the whole allocation and only released it on GC. Nothing owned the per-fragment buffer at all, and every fragment task holds one at the same time, so peak off-heap was the entire uncompressed cache plus the compression buffers, all charged againstMaxDirectMemorySize. A large modpack could fail withOutOfMemoryError: Direct buffer memorywhile the Java heap looked empty. - The cache is written to
<hash>.tmpand moved into place at the end. The save runs on a daemon thread, so it can be killed while the game shuts down, andexists()used to report the half written directory as a valid cache. The next launch then wasted a full load attempt on it. - Files written through a
MappedByteBufferare unmapped explicitly. The mapping outlives theFileChannel, and Windows then refuses to rename the directory, which made the atomic commit fail withAccessDeniedExceptionand discarded the cache on every save. - Fragment progress is reported from the calling thread now.
StepTaskcounts in a plain int, so reporting from inside the parallel fragment tasks lost updates and the progress bar could hang below 100%.
Cache loading
CachingDatapublished the loaded cache through plain fields, and wrote the status before the payload. A reload thread could see a matching status next to a null or stale value,active()then reported false, and the module silently fell back to vanilla. The fields are volatile and the payload is now built before the status is published.Dazyused a plain field with a null check and aresolve()that builds a whole object graph, reachable from the bake continuation on the reload executor and from the render thread. Both sides could pass the check and build two copies of the same quad. It is now double-checked locked.TranslationHelper.translationsis aConcurrentHashMap. It is read from the caching thread while the client thread can rewrite it on a language change, and aHashMapresize racing agetcan spin forever on HotSpot.
Baking
- Every quad of a model part was registered twice. The constructor called
getQuads(null)and thengetQuads(direction)for all six directions and sent all seven results throughwriter.add. The directional lists are filtered subsets, so they never deduplicate against the full list. Empty directions are now skipped as well, which also stops them burning a registry id each. - Block states are looked up through an index built once per block. Finding the index by scanning the possible states ran once per cached blockstate, so a save cost O(sum of N^2) state comparisons.
Toast
- The caching thread races the client.
DashToastStatemixed fields written by the cache thread with fields read by the render thread with no happens-before edge, which is not guaranteed on ARM. Those fields are volatile now, andsetFinishedwrites the done time before the status, so the render thread can no longer seeDONEnext to a stale timestamp and hide the toast again immediately. - Adding a toast touches a
DequeinsideToastManagerand is not thread safe. The failure path now builds and adds the toast on the client thread, andDashToastStateno longer reads the language manager off-thread. - The caching thread is a daemon now. It blocked shutdown otherwise.
- The
-1inDashToast.firstUpdateTimeis a named constant. The value is correct today only becauseupdate()assigns it before reading it a few lines later; move the assignment and the hide timer silently falls back to the save timestamp. - The fork join pool is no longer built with
asyncMode = true. That flag only means something for managed blocker pools; with it, work handed toinvokeorinvokeAllmay run on the calling thread, which broke the documented assumption thatDashObject.exportruns on a worker.
Configuration
- An empty or partially invalid config file no longer produces a
NullPointerException. Gson returns null for an empty file, and a partly invalid document deserializes into an instance with null fields. - The config is written to a temp file and moved into place, so a crash while saving can no longer leave an empty config behind.
Status api
CacheStatusBus.addListenerreturns a handle that removes the listener again.whenLoadedsubscribes before it checks the status, so the change toLOADcan no longer be missed between the two, and it unsubscribes itself so a single registration does not fire again on everyF3+T.- A listener that throws is logged and skipped. It used to abort
Cache.setStatus, which left the remaining listeners unnotified and broke the loading cache.
Файлы
dashloader-5.1.0-beta.9.8+26.3.jar(7.51 MiB)
ОсновнойМетаданные
Канал релиза
Beta
Номер версии
5.1.0-beta.9.8+26.3
Загрузчики
FabricQuilt
Версии игры
26.3
Загрузок
6
Дата публикации
04.10.2026
