The bug
When creating a custom dimension in a datapack, setting "natural" to false and "bed_works" to true causes a fatal error to console when a player tries to sleep. Despite it being logged as a fatal error, the game doesn't crash, but players are unable to sleep.
Attached is a world that demonstrates the issue, and a datapack that adds a dimension affected by it.
Code analysis
Code analysis by @unknown can be found in this comment.
Linked issues
is duplicated by 1
Attachments
Comments 2
I've attached the datapack from MC-249534 that changes the relevant settings in the End, which should be up-to-date to the latest dimension format as of 1.18.2. As of at least 22w12a, this does crash the singleplayer client in addition to logging a fatal error.
The problem appears as a client-side fatal error, but the problem is in the server. (All names here are Yarn name) TL;DR:
SleepFailureReason
does not define theText
for the error andtrySleep
does not check if the failure reason has null text.net.minecraft.entity.player.PlayerEntity.SleepFailureReason
defines several reasons for sleep failures. Most of them have associatedtext
, butNOT_POSSIBLE_HERE
andOTHER_PROBLEM
does not, so it is an instance of the enum class with the internal valuetext
set to null. The method for sleeping,net.minecraft.server.network.ServerPlayerEntity#trySleep
, returns aPair
whose left side indicates the failure reason to be sent to the client. If the player is already sleeping or is dead,OTHER_PROBLEM
is returned, andNOT_POSSIBLE_HERE
if the dimension is not natural. Whennet.minecraft.block.BedBlock#onUse
callstrySleep
, there is a check that makes sure the pair's left item (failure reason) is not null, then callsServerPlayerEntity#sendMessage
which sendsGameMessageS2CPacket
to the client, withSleepFailureReason#toText
as the message. *However, the check does not consider cases wheretoText
returns null*, which is when the failure reason isNOT_POSSIBLE_HERE
orOTHER_PROBLEM
.On client,
net.minecraft.client.network.ClientPlayNetworkHandler#onGameMessage
callsnet.minecraft.client.gui.hud.InGameHud#addChatMessage
. If the "hide matching names" options is true, it then callsInGameHud#extractSender
, which then callsnet.minecraft.client.font.TextVisitFactory#removeFormattingCodes
andTextVisitFactory#visitFormatted
wheretext.visit
call throwsNullPointerException
.