refactor: add why-comments to zone tiles, audio cache, socket buffer

- zone_manager: document tile-to-zone key encoding (tileX * 100 + tileY,
  safe because tileY < 64 < 100) and explain that ranges are empirically
  derived from the retail WoW map grid
- audio_engine: expand sample rate comment — miniaudio defaults to
  device rate causing pitch distortion if not set explicitly; name
  kMaxCachedSounds constant with memory budget explanation
- tcp_socket: add why-comment on 4 KB recv buffer sizing — covers
  typical 20-500 byte packets and worst-case ~2 KB UPDATE_OBJECT
This commit is contained in:
Kelsi 2026-03-30 14:52:51 -07:00
parent 8c7db3e6c8
commit d2a7d79f60
3 changed files with 20 additions and 5 deletions

View file

@ -98,8 +98,11 @@ static bool decodeWavCached(const std::vector<uint8_t>& wavData, DecodedWavCache
entry.sampleRate = sampleRate;
entry.frames = framesRead;
entry.pcmData = pcmData;
// Evict oldest half when cache grows too large (keeps ~128 most-recent sounds)
if (gDecodedWavCache.size() >= 256) {
// Evict oldest half when cache grows too large. 256 entries ≈ 50-100 MB of decoded
// PCM data depending on file lengths; halving keeps memory bounded while retaining
// recently-heard sounds (footsteps, UI clicks, combat hits) for instant replay.
constexpr size_t kMaxCachedSounds = 256;
if (gDecodedWavCache.size() >= kMaxCachedSounds) {
auto it = gDecodedWavCache.begin();
for (size_t n = gDecodedWavCache.size() / 2; n > 0; --n, ++it) {}
gDecodedWavCache.erase(gDecodedWavCache.begin(), it);
@ -239,7 +242,9 @@ bool AudioEngine::playSound2D(const std::vector<uint8_t>& wavData, float volume,
decoded.pcmData->data(),
nullptr // No custom allocator
);
bufferConfig.sampleRate = decoded.sampleRate; // Critical: preserve original sample rate!
// Must set explicitly — miniaudio defaults to device sample rate, which causes
// pitch distortion if it differs from the file's native rate (e.g. 22050 vs 44100 Hz).
bufferConfig.sampleRate = decoded.sampleRate;
ma_audio_buffer* audioBuffer = static_cast<ma_audio_buffer*>(std::malloc(sizeof(ma_audio_buffer)));
if (!audioBuffer) return false;
@ -394,7 +399,9 @@ bool AudioEngine::playSound3D(const std::vector<uint8_t>& wavData, const glm::ve
decoded.pcmData->data(),
nullptr
);
bufferConfig.sampleRate = decoded.sampleRate; // Critical: preserve original sample rate!
// Must set explicitly — miniaudio defaults to device sample rate, which causes
// pitch distortion if it differs from the file's native rate (e.g. 22050 vs 44100 Hz).
bufferConfig.sampleRate = decoded.sampleRate;
ma_audio_buffer* audioBuffer = static_cast<ma_audio_buffer*>(std::malloc(sizeof(ma_audio_buffer)));
if (!audioBuffer) return false;

View file

@ -296,7 +296,12 @@ void ZoneManager::initialize() {
};
zones[1657] = darnassus;
// Tile-to-zone mappings for Azeroth (Eastern Kingdoms)
// Tile-to-zone fallback mappings for Azeroth (Eastern Kingdoms).
// WoW's world is a grid of 64×64 ADT tiles per continent. We encode (tileX, tileY)
// into a single key as tileX * 100 + tileY (safe because tileY < 64 < 100).
// These ranges are empirically determined from the retail map layout and provide
// zone identification when AreaTable.dbc data is unavailable.
//
// Elwynn Forest tiles
for (int tx = 31; tx <= 34; tx++) {
for (int ty = 48; ty <= 51; ty++) {

View file

@ -139,6 +139,9 @@ void TCPSocket::update() {
bool sawClose = false;
bool receivedAny = false;
for (;;) {
// 4 KB per recv() call — large enough for any single game packet while keeping
// stack usage reasonable. Typical WoW packets are 20-500 bytes; UPDATE_OBJECT
// can reach ~2 KB in crowded zones.
uint8_t buffer[4096];
ssize_t received = net::portableRecv(sockfd, buffer, sizeof(buffer));