Hide post-login world hitch behind loading screen

- keep character-selection state until world entry load/finalize completes
- move expensive post-load setup (test transport + creature callback prep) before loading screen shutdown
- add bounded world warmup pass under loading screen to drain initial network/spawn backlog
- start intro camera pan after warmup so rotation begins when gameplay becomes visible
- guard test transport setup so it runs once per session
- add per-update world socket parse budget to prevent single-frame packet-drain stalls

This reduces visible 3-4s stutter after login by shifting startup work behind the loading screen and time-slicing packet processing.
This commit is contained in:
Kelsi 2026-02-20 17:29:09 -08:00
parent 954edc91b8
commit acb63d4f6e
3 changed files with 74 additions and 10 deletions

View file

@ -10,6 +10,7 @@
namespace {
constexpr size_t kMaxReceiveBufferBytes = 8 * 1024 * 1024;
constexpr int kMaxParsedPacketsPerUpdate = 220;
inline bool isLoginPipelineSmsg(uint16_t opcode) {
switch (opcode) {
@ -323,7 +324,8 @@ void WorldSocket::update() {
void WorldSocket::tryParsePackets() {
// World server packets have 4-byte incoming header: size(2) + opcode(2)
while (receiveBuffer.size() >= 4) {
int parsedThisTick = 0;
while (receiveBuffer.size() >= 4 && parsedThisTick < kMaxParsedPacketsPerUpdate) {
uint8_t rawHeader[4] = {0, 0, 0, 0};
std::memcpy(rawHeader, receiveBuffer.data(), 4);
@ -417,6 +419,12 @@ void WorldSocket::tryParsePackets() {
if (packetCallback) {
packetCallback(packet);
}
++parsedThisTick;
}
if (parsedThisTick >= kMaxParsedPacketsPerUpdate && receiveBuffer.size() >= 4) {
LOG_DEBUG("World socket parse budget reached (", parsedThisTick,
" packets); deferring remaining buffered data=", receiveBuffer.size(), " bytes");
}
}