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.java
soundSwitchRatio
now 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
soundNoveltyBonusWeight
duringsoundNoveltyTimeTicks
. - The async
candidateRecordById
mapping 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
soundScoringSubmitCooldownTicks
default is 1 to make async scoring responsive.
Defaults updated
soundSwitchRatio
default: 0.5soundNoveltyBonusWeight
default: 9.5
Added
-
Off-thread sound scoring integration
src/main/java/com/example/soundattract/SoundTracker.java
findNearestSound(mob, level, mobPos, mobEyePos, currentTargetSoundId)
now buildsSoundScoreRequest
with:- Mob position and time
- Current target sound ID to enforce switch ratio off-thread
- List of muffled
SoundCandidate
s (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
CallerRunsPolicy
with 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_TIME
andLAST_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
raycastCacheTtlTicks
andraycastCacheMaxEntries
. - Honors
enableRaycastCache
to 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.workerThreads
andCOMMON.workerTaskBudgetMs
if present). - Immutable snapshots:
MobSnapshot
,ConfigSnapshot
. - Result queue +
GroupComputeResult
for 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/hashCode
inside 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
164Publication date
August 25, 2025 at 3:15 PMPublisher

Sylsatra
Member