Compatibility
Minecraft: Java Edition
Platforms
Supported environments
Creators
Details
Changelog
[1.20.1-4.0.8] - 2025-08-25
Changed
-
Sound switching semantics clarified and updated
src/main/java/com/example/soundattract/config/SoundAttractConfig.javasoundSwitchRationow uses multiply semantics with ratio in (0.0–1.0]: switch whennewWeight > currentWeight × soundSwitchRatio.- Updated comments and bounds; default set to 0.5.
-
Novelty bonus applied consistently to effective weight
src/main/java/com/example/soundattract/SoundTracker.java- The effective weight returned for the selected sound now includes
soundNoveltyBonusWeightduringsoundNoveltyTimeTicks. - The async
candidateRecordByIdmapping also stores novelty-adjusted weight so async-picked IDs honor novelty.
- The effective weight returned for the selected sound now includes
-
Resolve same-soundId ambiguity
- When multiple candidates share a
soundId, keep the one with higher effective weight (including novelty); tie-breaker by closer distance to the mob.
- When multiple candidates share a
-
Config responsiveness tweaks
soundScoringSubmitCooldownTicksdefault is 1 to make async scoring responsive.
Defaults updated
soundSwitchRatiodefault: 0.5soundNoveltyBonusWeightdefault: 9.5
Added
-
Off-thread sound scoring integration
src/main/java/com/example/soundattract/SoundTracker.javafindNearestSound(mob, level, mobPos, mobEyePos, currentTargetSoundId)now buildsSoundScoreRequestwith:- Mob position and time
- Current target sound ID to enforce switch ratio off-thread
- List of muffled
SoundCandidates (range/weight after block muffling) soundSwitchRatio, novelty bonus and window (from config)
- Async results drained via
WorkerScheduler.drainSoundScoreResults()and cached per-mob.
src/main/java/com/example/soundattract/ai/AttractionGoal.java- Updated call sites (
canContinueToUse(),tick(),findInterestingSoundRecord()) to pass the current target sound ID intoSoundTracker.findNearestSound(...).
- Updated call sites (
-
Dynamic configuration keys (accessed via
SoundAttractConfig.COMMON.<key>.get()):soundScoringSubmitCooldownTicks(default 5)asyncResultTtlTicks(default 10)raycastCacheTtlTicks(default 200)raycastCacheMaxEntries(default 5000)
Changed
-
Worker scheduler rejection policy
src/main/java/com/example/soundattract/worker/WorkerScheduler.java- Replaced
CallerRunsPolicywith a non-blockingDiscardOldestPolicy-based handler to avoid main-thread stalls when saturated. - Added debug logging when tasks are dropped (gated by
debugLogging).
- Replaced
-
Per-mob async submission control in
SoundTracker- Added per-mob maps
LAST_SUBMIT_GAME_TIMEandLAST_CANDIDATE_HASH. - Submissions are skipped if within cooldown, async result is still fresh, and candidate set (incl. current target) is unchanged.
- Async result TTL and submission cooldown are now read from config.
- Added per-mob maps
-
Raycast cache eviction and gating
SoundTracker.applyBlockMuffling(...)cache now storesRaycastEntry(result, gameTime).- TTL-based expiry and size-based eviction implemented; values read from
raycastCacheTtlTicksandraycastCacheMaxEntries. - Honors
enableRaycastCacheto bypass both cache reads and writes when disabled.
Notes
-
All configuration values are looked up dynamically via
SoundAttractConfig.COMMON.<key>.get()to reflect live changes. -
Defaults for the new keys match previous hardcoded behavior for compatibility.
-
Debug logs are gated by
SoundAttractConfig.COMMON.debugLogging.get(). -
Added a worker scheduler and refactored mob grouping logic to run heavy math off-thread using snapshots, while applying results on the main thread.
Added
- Worker pool and DTOs
src/main/java/com/example/soundattract/worker/WorkerScheduler.java- Bounded daemon thread pool (safe defaults; optional config via
SoundAttractConfig.COMMON.workerThreadsandCOMMON.workerTaskBudgetMsif present). - Immutable snapshots:
MobSnapshot,ConfigSnapshot. - Result queue +
GroupComputeResultfor leader mapping, edge mobs, deserters.
- Bounded daemon thread pool (safe defaults; optional config via
Changed
-
Group computation off-thread and result application on tick
src/main/java/com/example/soundattract/ai/MobGroupManager.java- New
submitGroupComputeSnapshot(ServerLevel)to build snapshot (main thread) and submit worker task. - New
applyGroupResult(ServerLevel, GroupComputeResult)to rebuilduuidToLeader,leaders,lastEdgeMobMap,deserterUuids(main thread). updateGroups(ServerLevel)now uses an early-submit pattern; retains previous synchronous path as fallback.- Fixed inner class structure for
SoundRelay(keptequals/hashCodeinside the class).
- New
-
Apply results during server tick
src/main/java/com/example/soundattract/SoundAttractionEvents.java- In
onServerTick(END), drainWorkerScheduler.drainGroupResults()and apply viaMobGroupManager.applyGroupResult(...). - Preserved existing tick sequence (dynamic cooldown -> sound tracker -> block breaker -> apply group results -> pending goals).
- In
Notes
- All world/entity/goal access remains on the main thread; only pure computations are off-thread.
- Config lookups continue to use dynamic access (
SoundAttractConfig.COMMON.<key>.get()). Optional worker tunables are read via reflection with safe defaults. - Logs are gated behind
SoundAttractConfig.COMMON.debugLogging.get().
Files
Metadata
Release channel
ReleaseVersion number
4.0.8Loaders
Game versions
1.20.1Downloads
174Publication date
August 25, 2025 at 3:15 PMPublisher

Sylsatra
Member
![Attract to Sound ([NEO]Forge/Fabric): Sound & Stealth.](https://cdn.modrinth.com/data/zZluixcp/a53dfc770330e72a23452499f86e616adbe13ae3_96.webp)

