+size_t Packet::MakeJoin(const Entity &player, const string &world_name) noexcept {
+ constexpr size_t maxname = 32;
+
+ Tag();
+ header.type = JOIN;
+
+ uint8_t *cursor = &payload[0];
+
+ // TODO: generate entity IDs
+ *reinterpret_cast<uint32_t *>(cursor) = 1;
+ cursor += 4;
+
+ *reinterpret_cast<glm::ivec3 *>(cursor) = player.ChunkCoords();
+ cursor += 12;
+
+ *reinterpret_cast<glm::vec3 *>(cursor) = player.Position();
+ cursor += 12;
+ *reinterpret_cast<glm::vec3 *>(cursor) = player.Velocity();
+ cursor += 12;
+
+ *reinterpret_cast<glm::quat *>(cursor) = player.Orientation();
+ cursor += 16;
+ *reinterpret_cast<glm::vec3 *>(cursor) = player.AngularVelocity();
+ cursor += 12;
+
+ if (world_name.size() < maxname) {
+ memset(cursor, '\0', maxname);
+ memcpy(cursor, world_name.c_str(), world_name.size());
+ } else {
+ memcpy(cursor, world_name.c_str(), maxname);
+ }
+ cursor += maxname;
+
+ return sizeof(Header) + (cursor - &payload[0]);
+}
+
+size_t Packet::MakePart() noexcept {
+ Tag();
+ header.type = PART;
+ return sizeof(Header);
+}
+