Skip to content

Conversation

@danqzq
Copy link
Contributor

@danqzq danqzq commented Jan 12, 2026

Overview

This PR implements a complete bed system with sleeping mechanics and full multiplayer support. Players can now place beds, sleep through the night, and have their sleeping state synchronized across clients.

Demo

mcpe-beds

Additions

Core Bed System

  • Added BedTile class with directional placement logic (head/foot sections)
  • Added BedItem for placing beds based on player facing direction
  • Added BedSleepingProblem enum for sleep validation (daytime checks, distance validation, dimension restrictions)
  • Defined SHAPE_BED render shape and texture constants

Player Sleeping State

  • Added sleeping state fields: m_bSleeping, m_sleepTimer, m_bedSleepPos
  • Implemented Player::sleep() and Player::wake() methods
  • Implemented Level::updateSleeping() to advance time when all players are asleep

Rendering

  • Implemented tesselateBedInWorld() with proper UV rotation and wood underside rendering
  • Overrode setupPosition() and setupRotations() in HumanoidMobRenderer for sleeping player poses

Multiplayer Support

  • Added WAKE and SLEEP actions to AnimatePacket
  • Implemented sleep state broadcasting in ServerPlayer, LocalPlayer, and MultiplayerLocalPlayer
  • Added remote player sleep animation handling in ClientSideNetworkHandler

Changes

  • Registered bed in Tile::initTiles() and Item::initItems()
  • Modified camera behavior: locked position and rotation while sleeping with adjusted height
  • Changed pause/escape behavior to wake player instead of opening menu when sleeping
  • Players now become immobile during sleep
  • Face culling adjusted for connecting bed halves
  • Fixed bed respawn position handling in NetEventCallback and Minecraft::_resetPlayer()

Attribution

The following implementations were referenced from Wilyicaro/PEtoLE:

  • BedTile class - Core tile structure, getTexture() direction mapping, neighborChanged() logic, use() interaction, setBedOccupied(), getRespawnTilePos()
  • BedItem class - Direction calculation and placement validation
  • Player sleeping - sleep() / wake() implementations, updateSleepingPos(), getBedSleepRot(), sleeping position calculations
  • TileRenderer bed rendering - tesselateBedInWorld() with UV rotation and face direction handling
  • Static direction lookup tables - headBlockToFootBlockMap, hiddenFace, hiddenFaceIndex, bedDirection

Going Forward

  • Add screen dulling effect when sleeping initiates
  • Add proper error messages for BedSleepingProblem cases displayed to player
  • Add config option for sleep time advancement speed

Copy link
Collaborator

@BrentDaMage BrentDaMage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor things. Also, Visual Studio project files don't seem to be updated. I can fix this though.

@danqzq
Copy link
Contributor Author

danqzq commented Jan 13, 2026

@BrentDaMage I've made changes based upon your requests. Based on your feedback I've changed the way the sleeping state is synchronized (now via InteractionPacket), let me know if you're satisfied with it.

P.S I'm on macOS so I can't generate the Visual Studio project files.

}
}

void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& rakGuid, InteractionPacket* pkt)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot do InteractionPacket, this breaks compatibility with actual Pocket Edition/Bedrock. Also, couldn't we just handle this the same way we handle every other block interaction received by the server?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, I forgot that networking-wise we should follow MCPE standards. As far as I'm aware, other blocks like doors handle block interactions via UpdateBlockPacket, but I don't think this is suitable for beds. If not InteractionPacket, then why not UseItemPacket? Would that not be compatible?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the server receives interactions from clients via UseItemPacket, then that's what we should use.


void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& guid, InteractionPacket* packet)
{
// InteractionPacket is broadcast-only, used to synchronize actions like sleeping
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't even need to have InteractionPacket, if its sole purpose is to animate the player on the client-side, just use SynchedEntityData.

@BrentDaMage BrentDaMage added the enhancement New feature or request label Jan 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants