-
Bug
-
Resolution: Won't Fix
-
None
-
1.20.1
-
None
-
Confirmed
-
(Unassigned)
When playing a jukebox at a low TPS, for example, 10. The timer to find out when the music disk ends and update the comparator takes twice as long as the song, since the client sound manager is unaffected by TPS.
Code analysis
The relevant code is in JukeboxBlockEntity
private long tickCount; private long recordStartedTick; private boolean isPlaying; private void tick(Level level, BlockPos pos, BlockState state) { ++this.ticksSinceLastEvent; if (this.isRecordPlaying()) { Item var5 = this.getFirstItem().getItem(); if (var5 instanceof RecordItem recordItem) { if (this.shouldRecordStopPlaying(recordItem)) { this.stopPlaying(); } else if (this.shouldSendJukeboxPlayingEvent()) { this.ticksSinceLastEvent = 0; world.gameEvent(GameEvent.JUKEBOX_PLAY, pos, GameEvent.Context.of(state)); this.spawnMusicParticles(world, pos); } } } ++this.tickCount; } private boolean shouldRecordStopPlaying(RecordItem disc) { return this.tickCount >= this.recordStartedTick + (long)disc.getLengthInTicks() + 20L; }
As you can see, there is no accounting for TPS.
My solution would be to converting tickCount to a double, replacing ++this.tickCount; with this.tickCount += 20 / tps; so each tick can actually account for more than a single tick.
When serializing to NBT, this can be kept backwards compatible by just rounding back to long (how it is saved), as at most this can lose a single tick per save/load cycle.