Player interaction ripples: vertex shader adds radial damped-sine displacement
centered on player position, fragment shader adds matching normal perturbation
for specular highlights. Player XY packed into shadowParams.zw, ripple strength
into fogParams.w. Separate 1x render pass for water when MSAA is active to
avoid MSAA-induced darkening — water renders after main pass resolves, using
the resolved swapchain image and depth resolve target. Water 1x framebuffers
rebuilt on swapchain recreate (window resize).
- Add .setMultisample() to minimap display pipeline and recreatePipelines() for MSAA changes
- Defer all swapchain recreation in window.cpp to beginFrame() via markSwapchainDirty()
to prevent mid-frame render pass destruction crashes on resolution/fullscreen change
- Move spawnPlayerCharacter() call to after loadTestTerrain() where character renderer exists
MSAA change was called mid-frame from settings UI, destroying the render pass
and framebuffers while the command buffer was still recording. Now deferred
via pendingMsaaSamples_ flag, applied in beginFrame() before any GPU state.
Also add +180° to M2 game object orientation to fix facing direction.
Replace all glGenTextures/glTexImage2D calls in UI code with Vulkan texture
uploads via new VkContext::uploadImGuiTexture() helper. This fixes segfaults
from calling OpenGL functions without a GL context (null GLEW function pointers).
- Add uploadImGuiTexture() to VkContext with staging buffer upload pattern
- Convert game_screen, inventory_screen, spellbook_screen, talent_screen
from GLuint/GL calls to VkDescriptorSet/Vulkan uploads
- Fix loading_screen clearValueCount (was 1, needs 2 or 3 for MSAA)
Skybox: replace sphere-mesh approach with a fullscreen triangle that
reconstructs the world-space ray direction analytically via inverse
projection/view matrices. Eliminates clip.w=0 degeneracy at the horizon
and correctly maps altitude to dir.z in the Z-up coordinate system.
Clouds: hemisphere mesh was storing altitude in aPos.y (Y-up convention);
the Z-up view matrix projected this sideways, making clouds appear
vertical. Store altitude in aPos.z and update the fragment shader to
read dir.z as altitude and dir.xy as the horizontal UV plane.
- renderWorld() now calls wmoRenderer, characterRenderer, m2Renderer (+smoke,
particles) in the correct opaque→transparent order; water moved after all
opaques; per-subsystem timing active in live path
- Deleted the 310-line #if 0 GL stub block and removed #include <GL/glew.h>
(last GL reference in renderer.cpp)
- Full-screen overlay pipeline (postprocess.vert + overlay.frag, alpha blend,
no depth test/write) for underwater tint; lazily initialized, renders a blue
tint when camera is meaningfully below the water surface; canal vs open-water
tint colours preserved from original design
- overlay.frag.glsl / overlay.frag.spv added
- render sun with alpha blend while keeping moon additive glow
- add dedicated always-running sun haze timer (decoupled from moon phase cycling)
- constrain sun sprite with radial alpha mask and low-alpha discard to remove square artifact
- tune sun tint warmer without over-yellowing
- replace noisy/pulsing haze with slower flow-warp turbulence and lower amplitude
- add one-time warning caches for missing CreatureDisplayInfo and missing model path lookups
- log each missing displayId/model-path only once instead of every spawn retry/frame
- remove duplicate empty-model-path warning in spawnOnlineCreature (already reported by lookup path)
This cuts high-frequency log I/O and string formatting in hotspots when server sends unknown displayIds, while preserving first-occurrence diagnostics.
- ensure player transform sync is not gated by third-person so player shadow stays consistent
- hold shadow projection center during movement and snap once on stop to remove delayed catch-up
- smooth foliage caster transitions using blended phase-shifted UV samples
- tune foliage motion frequencies/amplitudes for less popping
- increase shadow map resolution to 2048 and retune terrain PCF texel scale
- increase global shadow strength from 0.62 to 0.68 for stronger, clearer shadows
- keep shadow projection center fixed while moving to remove per-frame projection churn flicker
- replace delayed post-move catch-up with immediate stop transition and idle smoothing
- rework foliage shadow caster motion to use blended phase-shifted UV samples for continuous position transitions
- reduce high-frequency foliage threshold popping by removing threshold warping path
- sharpen terrain receive filtering with tuned 5-tap PCF weights/offset for more detailed shadows
- raise shadow map resolution to 1536 and keep light-space texel snapping for stable sampling
- set shadows enabled by default and lower global shadow strength from 0.65 to 0.62
- keep foliage animation speed consistent between moving and idle at 80%
- reduce per-tile ground clutter generation pressure and enforce tighter caps to avoid spikes
- remove expensive detail dedupe scans from the hot render path
- add progressive/lazy clutter updates around player movement to smooth frame pacing
- lower noisy runtime INFO logging to DEBUG/throttled paths
- keep terrain/game screen updates responsive while preserving existing behavior
Add page-text support for sign-like gameobject interactions by handling SMSG_GAMEOBJECT_PAGETEXT and SMSG_PAGE_TEXT_QUERY_RESPONSE, and issuing CMSG_PAGE_TEXT_QUERY when page IDs are available from cached GO template data.
Normalize received page text tokens before chat display and add a fallback for basic signpost GO type clicks to print sign names when no page data is present.
Correct M2 gameobject yaw alignment for signposts/arrows by applying render-space -90deg offset consistently across spawn, position update, and move-callback transforms; keep WMO orientation path unchanged.
Normalize WoW quest text tokens during parsing so quest titles/details no longer leak raw markup like and |n into UI. Apply to WotLK and Classic parser paths, including quest list parsing in GameHandler.
Harden quest state handling by mapping abandon requests to authoritative server quest-log slots (PLAYER_QUEST_LOG_START) instead of local vector order, with a guarded fallback when update fields are unavailable.
Improve accept de-duplication by trusting server slot state over stale local cache; allow re-accept when local/server state diverges and trigger resync semantics.
Add expansion-aware CMSG_QUESTGIVER_ACCEPT_QUEST builders: WotLK sends guid+questId+unk1(uint32), while TBC/Classic/Turtle send guid+questId only. Wire GameHandler through PacketParsers for compatibility across expansions and cores.
- resolve creature virtual item values as Item.dbc entry -> DisplayID before direct ItemDisplayInfo fallback\n- use correct WotLK virtual item base index set (starting at 56) and keep retry attach loop for late update fields\n- keep NPC main-hand weapon attachment path and clear erroneous offhand attachments\n- refactor NPC virtual weapon attach into helper with per-creature retry tracking\n- tighten humanoid facial hair geoset selection to avoid loading all beard/sideburn meshes\n- adjust facial 3xx preference to favor chin-hair channel when available
Add configurable fade-in support to MusicManager playback paths and use it for auth/login intro tracks to avoid abrupt starts. Apply a login-only 20% music attenuation while the auth screen is active, then restore the previous music volume when leaving login so in-game volume remains unchanged.
Hide NPC cloak/object-skin mesh when no cape texture resolves by using a transparent texture fallback, preventing skin-texture bleed on cloaks. Tighten NPC equipment region compositing by slot and add safe humanoid geoset selection to avoid robe-over-pants conflicts and odd pants texturing.
Reduce login/runtime hitching by deferring non-critical world-system initialization across frames, lowering per-frame transport doodad spawn budget, and demoting high-volume transport/MO_TRANSPORT diagnostics to debug. Gate M2 glow diagnostics behind WOWEE_M2_GLOW_DIAG and make zone music prewarm opt-in via WOWEE_PREWARM_ZONE_MUSIC.
- Add per-frame cap for first-time creature model loads to spread expensive model/texture decode work across frames instead of burst loading.
- Keep cached creature spawns flowing while deferring uncached display IDs, preserving world population updates with smoother frame pacing.
- Defer transport WMO doodad instancing into a queued batch processor with a strict per-frame budget to avoid multi-hundred-ms spikes when ships/elevators register.
- Process deferred transport doodad batches in both normal gameplay update and loading-screen warmup loop so heavy transport setup can be amortized before and after world entry.
- Cleanup pending transport doodad batches on gameobject despawn to prevent stale work and avoid attaching children to removed parents.
- Lower character texture cache miss logging from INFO to DEBUG to reduce log I/O contention during movement-heavy asset streaming.
- Keep WotLK chest flow stock-like by relying on GAMEOBJ_USE/REPORT_USE instead of forcing eager CMSG_LOOT.
- Preserve fallback eager-loot behavior for Classic/Turtle paths with bounded retries.
- Improve GO targeting usability by allowing gameobject pick/retarget in world click logic.
- Remove temporary loot/chest diagnostic LOG_INFO traces added during chest-open debugging.
Declare autoAttackOutOfRangeTime_ and autoAttackRangeWarnCooldown_ in GameHandler to match existing combat logic in game_handler.cpp and keep header/source state in sync.
Allow equipped bags to be moved through the shared inventory pickup/drop flow, including dragging from bag contents to bag bar and back from bag bar into bag/backpack slots.
Changes:
- Add InventoryScreen APIs to begin pickup from an equipment slot and drop held item into a target equipment slot.
- Treat inventory type 18 (bags) as valid drops on BAG1-BAG4 during slot validation.
- Route equipment placement in online mode through swapContainerItems with explicit src/dst addressing for deterministic bag slot moves.
- Update bag bar hover-drop path to use InventoryScreen drop API instead of direct local slot mutation.
- On bag bar drag start, hand off to inventory held-item drag when inventory/character UI is open so drops into bag/backpack slots work.
- 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.
- add idempotent pending-accept tracking with timeout and per-quest cleanup hooks
- stop optimistic local quest insertion on accept; rely on server-authoritative updates
- handle QUEST_INVALID already-on/completed as reconciliation paths for pending accepts
- trigger quest metadata + status resync when accept state drifts
- add login-time quest log rebuild from PLAYER_QUEST_LOG server slots
- query quest metadata for server-slot quests to hydrate titles/objectives
- clear stale pending quest accept/query state on fresh world entry
- improve gossip quest selection fallback by trusting server quest slots when local cache is missing
This reduces duplicate accept/state mismatch loops (notably reason=13) and stabilizes WotLK quest behavior after relogs.
- Use interpolated moveInstanceTo() for normal server NPC position deltas so walk/run animations play instead of visual sliding
- Keep hard snaps only for dead units and large corrections/teleports
- Add per-creature render position cache to drive interpolation safely across frames and clear it on spawn/despawn/reset
- Keep minimap controls visible regardless of quest-status availability
- Correct minimap NPC/quest marker projection mapping to match minimap shader transform
- Add optional nearby NPC minimap dots setting (default OFF), exposed in Gameplay > Interface and persisted in settings
- Right-click attack fallback for non-interactable hostile creatures
- Robust creature skin path resolution for WotLK/non-humanoid display skin fields
- Strengthened client-side anti-overlap spacing for active melee targets (including wolf/worg models)
- Minimap questgiver markers now use live minimap view radius and exact minimap center to prevent player-relative drift
Selection ring rendering has been upgraded to better match WoW-like target feedback and remain readable across complex geometry.
Visual updates:
- Reworked ring mesh/shader from a simple two-band strip to a unit-disc + radial fragment shaping.
- Implemented a thinner outer ring profile.
- Added an inward color/alpha gradient that fades from the ring toward the center.
Placement/anchoring updates:
- Added CharacterRenderer::getInstanceFootZ() to query model foot plane from instance bounds.
- Added Application::getRenderFootZForGuid() to resolve per-GUID foot height via live instance mapping.
- Updated GameScreen target selection placement to anchor the effect at target foot Z.
Ground/surface stability:
- In renderSelectionCircle(), added floor clamping against terrain, WMO, and M2 floor probes at target XY.
- Raised final placement offset to reduce residual clipping on uneven surfaces.
Depth/visibility behavior:
- Added polygon offset during ring draw to reduce z-fighting.
- Disabled depth testing for the selection effect draw pass (with state restore) so the ring remains visible through terrain/WMO occluders, per requested behavior.
State safety:
- Restored modified GL state after selection pass (depth test / polygon offset / depth mask / cull).
Build validation:
- Verified with cmake build target "wowee" after each stage; final build succeeds.
Combat state/UI:
- Split attack intent from server-confirmed auto attack in GameHandler.
- Add explicit combat state helpers (intent, confirmed, combat-with-target).
- Update player/target frame and renderer in-combat indicators to use confirmed combat.
- Add intent-only visual state in UI to avoid false combat feedback.
Animation correctness:
- Correct combat-ready animation IDs to canonical ready stances (22/23/24/25).
- Remove hit/wound-like stance behavior caused by incorrect ready IDs.
Classic/TBC/Turtle melee reliability:
- Tighten melee sync while attack intent is active: faster swing resend, tighter facing threshold, and faster facing cadence for classic-like expansions.
- Send immediate movement heartbeat after facing corrections and during stationary melee sync windows.
- Handle melee error opcodes explicitly (NOTINRANGE/BADFACING/NOTSTANDING/CANT_ATTACK) and immediately resync facing/swing where appropriate.
- On ATTACKSTOP with persistent intent, immediately reassert ATTACKSWING.
- Increase movement heartbeat cadence during active classic-like melee intent.
Server compatibility/anti-cheat stability:
- Restrict legacy force-movement/speed/teleport ACK behavior for classic-like flows to avoid unsolicited order acknowledgements.
- Preserve local movement state updates while preventing bad-order ACK noise.
Resolved a melee desync where attacks could fail unless constantly moving through target.
Movement opcode handling:
- In 0x006B compatibility path, prefer compressed-move batch detection before weather alias routing.
- Route 0x006B payloads shaped like SMSG_COMPRESSED_MOVES sub-packets to handleCompressedMoves().
Root/unroot state synchronization:
- Added handling for SMSG_FORCE_MOVE_ROOT and SMSG_FORCE_MOVE_UNROOT.
- Added handleForceMoveRootState() to apply server-authoritative ROOT flag locally.
- Send CMSG_FORCE_MOVE_ROOT_ACK / CMSG_FORCE_MOVE_UNROOT_ACK with current movement payload and counter.
Melee facing stability:
- Added periodic facing sync during auto-attack (MSG_MOVE_SET_FACING) when angular drift to target exceeds threshold.
- Keeps server front-arc/facing checks aligned while stationary meleeing.
Noise reduction / stream hygiene:
- Consume optional legacy/system packets safely: SMSG_FRIEND_LIST, SMSG_IGNORE_LIST, SMSG_ADDON_INFO, SMSG_EXPECTED_SPAM_RECORDS.
Validation:
- Rebuilt successfully with cmake --build build -j32.
Introduce data-driven opcode registry with canonical and alias sources:
- Added Data/opcodes/canonical.json as the single canonical LogicalOpcode set.
- Added Data/opcodes/aliases.json for cross-core naming aliases (CMaNGOS/AzerothCore/local legacy).
Added generator and generated include fragments:
- tools/gen_opcode_registry.py emits include/game/opcode_enum_generated.inc, include/game/opcode_names_generated.inc, and include/game/opcode_aliases_generated.inc.
- include/game/opcode_table.hpp now consumes generated enum entries.
- src/game/opcode_table.cpp now consumes generated name and alias tables.
Loader canonicalization behavior:
- OpcodeTable::nameToLogical canonicalizes incoming JSON opcode names via alias table before enum lookup, so implementation code stays stable while expansion maps can use different core spellings.
Validation and build integration:
- Added tools/validate_opcode_maps.py to validate canonical contract across expansions.
- Added CMake targets opcodes-generate and opcodes-validate.
- wowee target now depends on opcodes-generate so generated headers stay current.
Validation/build run:
- cmake -S . -B build
- cmake --build build --target opcodes-generate opcodes-validate
- cmake --build build -j32
Classic: synchronized Data/expansions/classic/opcodes.json to /home/k/Desktop/classicopcodes.h with exact symbol/value parity (0 missing, 0 mismatches).
WotLK: synchronized Data/expansions/wotlk/opcodes.json to /home/k/Desktop/azerothcoreOpcodes.h and aligned symbol names to AzerothCore naming.
Logical opcode layer: expanded include/game/opcode_table.hpp and src/game/opcode_table.cpp to include missing canonical opcode symbols required by synced tables, and removed legacy alias fallback block so canonical names are used directly.
Gameplay/handler updates included from ongoing fixes: duel/taxi stale opcode cleanup, level-up/sound handling adjustments, and related parser/packet references updated to match canonical opcode identifiers.
Validated by successful full build: cmake --build build -j32.